My typical JavaScript interview

It is not easy to find a good JavaScript resource, and it also challenging to come up with the proper set of questions to determine whether the candidate be a good match. I know a lot of colleagues that simply ask very generic or theoretical questions during the interview process, but for me the main indication is the person’s ability to produce the good quality code under short period of time. My interview usually takes around 45 minutes where interviewee writes a code over skype sharing. One of the typical tasks I give is to create a tabview component + several other basic components inside of the TabView class. I prefer candidates to use native JavaScript to see if they know fundamentals rather then simply relying on frameworks. Being expert in framework is enough for website developer, but for any serious Single page app the core JS skills are critical.

Anyways, here’ the good enough answer to my TabView task developed by me in 25 minutes.

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<html>
<style>
#tabs li{display: inline;list-style-type: none;padding-right: 20px;}
#tabs li a { color: black; background: white; text-decoration: none; }
#tabs li a:hover { background: #ccc; }
</style>
<ul id="tabs">
<li><a href="graph" id="0">Graph</a></li>
<li><a href="list" id="1">List</a></li>
<li><a href="tree" id="2">Tree</a></li>
</ul>
<div id="graph"></div>
<div id="list"></div>
<div id="tree"></div>
<script>
    function bind(scope, fn) {
   return function () {
   fn.apply(scope, arguments);
   };
    }
    
    function TabView(el, options) {
        this.el = document.querySelector(el);
        this.options = options || {};
        this.render();
        this.bindUI();
    }
    
    TabView.prototype = {
        render: function(){
            this.clear();
            this.options.tabContents[this.options.activeTab].render();
        },
        clear: function(){
            this.options.tabContents[this.options.activeTab].el.innerHTML = "";
        },
        bindUI: function(e)
        {
            this.el.addEventListener("click", bind(this, this._handleTabClicked), false);
        },
        _handleTabClicked: function(evt){
            evt.preventDefault();
            var target = evt.target,
                targetId = evt.target.id;
            this.options.activeTab = parseInt(targetId, 10);
            this.render();
        }
    };
    function Graph(){
        this.el = document.getElementById("list");
        this.render = function(){
            this.el.innerHTML = "Graph";
        };
    }
    function List(){
        this.el = document.getElementById("list");
        this.render = function(){
            this.el.innerHTML = "List";
        };
    }
    function Tree(){
        this.el = document.getElementById("list");
        this.render = function(){
            this.el.innerHTML = "Tree";
        };
    }
    var tabView = new TabView('#tabs', {
        activeTab: 1,
        tabContents: [ new Graph(), new List(), new Tree() ]
    });
</script>
</html>

Node.ACS gotchas

Node.ACS is pretty exciting framework for getting your node.js applications to talk to the Cloud. I started with step by step documentation on
Getting Started with Node.ACS but got stuck on the step where I needed to authenticate before creating users and places.

Gotcha #1:

- Use the proper key/secret in ACS.init(‘my_oauth_key’, ‘my_oauth_secret’); Note that there’s both development and production pairs.
I spend more than hour, and pinging Arthur Evans before realizing it.

Gotcha #2

- You can call ACS related functions only in the scope of api namespace. I tried invoking ACS.Places.create from private function, but it didn’t work

Gotcha #3

- Remember that everything in Node.js need to be asynchronous and be careful about what parameters you pass to callback functions (api.login(req, res, api.createPlace);)

I posted my code on github https://github.com/opolyo01/nodeACS

Closure 101 and issues with the for loop

Clicking on any li element would always give the last index 5

JavaScript
1
2
3
4
5
6
7
8
9
10
11
function addLinks () {
    for (var i=0, link; i<5; i++) {
        link = document.createElement("a");
        link.innerHTML = "Link " + i;
        link.onclick = function () {
            alert(i);
        };
        document.body.appendChild(link);
    }
}
window.onload = addLinks;

The correct implementation [0, 1, 2, 3, 4]

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
function addLinks () {
    for (var i=0, link; i<5; i++) {
        link = document.createElement("a");
        link.innerHTML = "Link " + i;
        link.onclick = function (num) {
            return function () {
                alert(num);
            };
        }(i);
        document.body.appendChild(link);
    }
}
window.onload = addLinks;

Adding delegates and resigning first responder to all the textfields inside the UIViewController

I wanted to share something that I started to use recently to speed up my process of assigning delegates to textfields, particularly for them to be able to resign the first responder.

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return NO;
}
- (void)viewDidLoad
{
[super viewDidLoad];
for (UITextField *field in self.view.subviews)
{
if ([field respondsToSelector:@selector(setDelegate:)])
{
field.delegate = self;
}
}
    
}

The key thing about the code bellow is that we looping through each subview, and checking that field responds to setDelegate: method. Remember that if the subview doesn’t respond to delegate method, we will get an exception.

Node.js – Counting total number of lines of all the files with some extension recursively

I am sure there is a faster way to get the total number of lines of code with the certain file extension recursively, but I like JS, so I decided to write a simple node program to achieve it.

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
var fs = require('fs'),
    sys = require('util'),
    exec = require('child_process').exec,
    child,
    totalLines = 0;
var walk = function(dir, done) {
fs.readdir(dir, function(err, list) {
if (err) return done(err);
var pending = list.length;
if (!pending) return done(null, totalLines);
list.forEach(function(file) {
file = dir + '/' + file;
    
fs.stat(file, function(err, stat) {
if (stat && stat.isDirectory()) {
walk(file, function(err, res) {
if (!--pending) done(null, totalLines);
});
} else {
            var ext = file.substring(file.lastIndexOf('.') + 1);
            if(ext === "m" || ext === "h"){
                var path = fs.realpathSync(file);
                child = exec("wc -l "+path, function (error, stdout, stderr) {
                    var num = stdout.split("/");
                    num = parseInt(num[0]);
                    if(num)
                        totalLines += num;
                });
            }
if (!--pending) done(null, totalLines);
}
});
});
});
};
walk(".", function(err, results) {
if (err) throw err;
console.log(results);
});

I feel that node is perfect for scripting. I will use it for writing file manipulations, db scripts, and other sort of automation that comes around.

JavaScript interview questions

JavaScript
1
2
3
4
5
var x; console.log(typeof x);//undefined - operator
var x; console.log(typeof(x));//undefined - function
console.log(x == null); //true
console.log(x === null); //false
console.log(y);//ReferenceError: y is not defined

Which one is the correct way to assign empty object pointer to variable? var x = null; or var x = undefined;

JavaScript
1
2
3
4
5
!!"test" //true
Boolean(undefined) //false
Boolean(null) //false
Boolean(0) //false
Boolean(5) //true

Rounding errors when doing floating-point arithmetic

JavaScript
1
2
3
4
5
var a = 0.15; var b = 0.15; if (a + b == 0.3){console.log("yes");}else{console.log("no");} //yes
var a = 0.1; var b = 0.2; if (a + b == 0.3){console.log("yes");}else{console.log("no");} //no
console.log(parseInt("test")); //NaN
console.log(parseInt("test1234")); //NaN
console.log(parseInt("56test1234")); //56

Copying Values

JavaScript
1
2
var x =5, y =x; x = 20; console.log(y); //5
var x = [], y = x; x.name = "Oleg"; console.log(y.name); //Oleg

What methods and properties each instance of Object has?

JavaScript
1
2
3
4
5
6
7
8
9
10
var b = new Object();
Object
constructor: //function that creates an object
hasOwnProperty: //indicates whether given property exist on the object not prototype
isPrototypeOf: //determines if the object prototype of another object
propertyIsEnumerable: //can we use for-in
toLocaleString: //string representation for locale
toString: //string representation
valueOf: //returns a string, number, or Boolean equivalent of the object, often the same as toString()

Can primitive in JS have properties? //no

JavaScript
1
2
3
var name = "test";
name.age = 30;
console.log(name.age);//undefined

Are arguments passed by value or reference? // always values passed by value even object types

JavaScript
1
2
3
4
5
6
7
8
function setName(obj){
obj.name = "Oleg";
obj = [];
obj.name = "Tonya";
}
var person = [];
setName(person);
console.log(person.name); //Oleg

Calling Objective C from JavaScript and vise versa

Call JavaScript from ObjC method passing multiple arguments :

Objective-C
1
2
3
4
5
6
7
8
NSArray *arr = [NSArray arrayWithObjects:argument1, argument2, argument3, nil];
[[self windowScriptObject] callWebScriptMethod:@"displayMessage" withArguments:arr];
NSString *jsCommand = [NSString stringWithFormat:@"jsMethod(%d, %d, %d);",
argument1, argument2, argument3];
[self.webView stringByEvaluatingJavaScriptFromString:jsCommand];
[[self windowScriptObject] evaluateWebScript:@"callSomeJSMethod();"];

Calling ObjC from JS

  • Register methods that you want to expose:
    Objective-C
    1
    2
    3
    4
    5
    6
    7
    8
    + (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector {
    if(aSelector == @selector(doStuff)){
    return YES;
    }
    else{
    return NO;
    }
    }
  • Map your method names, so no need to invoke with _ (selectors in objc have : but they getting converted to _ in js)
    Objective-C
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    + (NSString *)webScriptNameForSelector:(SEL)sel
    {
    NSArray *methodsArr = [[NSArray alloc] initWithObjects:kCocoaMethods];
    [methodsArr autorelease];
    NSString *cocoaMethodStr = NSStringFromSelector(sel);
    if([methodsArr containsObject:NSStringFromSelector(sel)]){return [[cocoaMethodStr componentsSeparatedByString:@":"] objectAtIndex:0];
    }
    return nil;
    }

  • Register your Cocoa Controller either through custom class or self

    Objective-C
    1
    2
    3
    4
    5
    6
    - (void)webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)windowObject forFrame:(WebFrame *)frame
    {
    ILOGMyJSClass *myjsclass = [[MyJSClass alloc]init];
    [windowObject setValue:self forKey:@"Controller"];
    [windowObject setValue:myjsclass forKey:@"Controller2"];
    }

  • Then you can simply declare your public methods

    Objective-C
    1
    2
    3
    4
    5
    -(void)doStuff{
    LOG_INFO(@"Never called from JavaScript");
    }-(void)doStuffIncluded{
    LOG_INFO(@"Called from JavaScript included.");
    }

One interesting thing that I discovered that if you are calling Cocoa from WebInspector and you pass arguments of pointer type such strings -> NSString *, the Cocoa will receive them as null. It works as expected when you don’t run it in WebInspector, meaning the string being passed to ObjC methods.

By the way here’s the command to execute from terminal to enable WebInspector:
$ defaults write appIdentifier WebKitDeveloperExtras -bool true

appIdentifier is the identifier under the project summary that you can see in XCode.

Useful References

Memory Management in non-arc environment – release vs nil objects

I see people using a combination of setting ivars to nil and/or using release on them. After talking with a few Obj C experts, the recommended way is to
release ivars and no need nil them. If we set the ivar to nil, then the retain count immediately goes to 0.

Here’s the code snippet that proves this theory.

Objective-C
1
2
3
4
5
6
7
8
9
NSMutableString *str = [[NSMutableString alloc] initWithString:@"Hello World"];//1
NSLog(@"retain count %lu", [str retainCount]);
[str retain];//2
[str retain];//3
NSLog(@"retain count %lu", [str retainCount]);
[str release];//2
NSLog(@"retain count %lu", [str retainCount]);
str = nil;//0
NSLog(@"retain count %lu", [str retainCount]);

Another interesting finding that if you use the NSString instead of NSMutableString the initial retain count on alloc will be UINT_MAX

Objective-C
1
2
NSString *str = [[NSString alloc] initWithString:@"Hello World"];
NSLog(@"retain count %lu", [str retainCount]);//18446744073709551615
Here’s the stackoverlow that I got some of my answers from:
NSString behavior