JavaScript, Complete Weirdness

1 - Object Properties

var engineer = {
    name: "Erdi Taner Gokalp",
    languages: ["JavaScript", "Scala"],
    "&description": function() {
        return "I am a Front-end Engineer";
    }
};

var _name = "name";

engineer.name // Erdi Taner Gokalp
engineer["name"] // Erdi Taner Gokalp
engineer[_name] // Erdi Taner Gokalp
engineer["&description"]() // // I am a Front-end Engineer
engineer.&description() // ERROR!

JavaScript, Complete Weirdness

2 - Function Arguments

/*
JavaScript function's arguments are special data type which is called "array-like object" contains an index for each     argument and a length property. However, if you want to use them as an array, you need to call the "Array.prototype.slice.call(arguments, 0)" method.
*/

function concat() {
    var args = Array.prototype.slice.call(arguments, 0);
    return (function _concat(_args) {
        if (_args.length === 0) {
            return "";
        }
        return _args[0] + _concat(_args.slice(1, _args.length));
    })(args);
}

JavaScript, Complete Weirdness

3 - Truthy & Falsy Values

/* the followings are considered as falsy */

false
null
undefined
0
""
person.x // undefined property


/* result of a logical expression is not always a real boolean */

var obj = {
    x: "hello",
    y: 0
};

var defaultGreet = obj.x || "hallo"; // "hello"
var defaultNumber = obj.y || 1; // ?
var defaultBoolean = obj.z || true; // ?

JavaScript, Complete Weirdness

4 - Equality

1 == 1 // true
2 == "2" // true
1 == 2 // false

"" == false // true
[] == false // true
null == undefined // true

/* the triple equality check (=== or !==) compares value and type */

1 === 1 // true
1 === "1" // false
1 === parseInt("1") // true
[] === false // false
null === undefined // false

/* Objects are always compared by their reference!!! */

var person = { name: "taner};
var otherPerson = person;

person === otherPerson // true
person === {name: "taner"} // false

JavaScript, Complete Weirdness

5 - Scope

/*
Until ES6, JavaScript only supported the "function scopes". Block scoping was not available for control structures like switch, if, for, while.
*/

var args = [1, 2, 3, 4, 5];

function sum() {
    console.log(args); // ?

    var args = Array.prototype.slice.call(arguments, 0);
    var result = _sum(args);

    console.log(args); // ?    

    function _sum(_args) {
        var result = 0;
        
        console.log(result); // ?

        for (var i = 0; i < _args.length; i++) {
            var currentItem = _args[i];
            result += currentItem;
        }
        console.log(currentItem); // ?
        console.log(i); // ?
        
        return result;
    }

    console.log(result); // ?
    console.log(currentItem); // ?
    
    return result;
}

console.log(args);

var result = sum(args);
console.log(result);

JavaScript, Complete Weirdness

6 - Closures

/*
    How would the output of these execution of given code be ?
    What is the problem here ?
    How would you provide the output like :
    5, 6
    10, 11
    15, 16
    20, 21 ?
*/


var data = [5, 10, 15, 20];

for (var i = 0; i < 4; i++) {
    asyncIncrement(data[i], function(result) {
        console.log(i, result); // ?
    });
}

function asyncIncrement(data, callback) {
    setTimeout(function() {
        callback(++data);
    }, 4000);
}

JavaScript, Complete Weirdness

6 - Global Variables

/*
    variables declared without "var" keyword will automatically become global. (in Node, they will be global to the module)
*/

var result = 15;

function sum() {
    result = Array.prototype.slice.call(arguments, 0).reduce(function(result, current) {
        result += current;
        return result;
    }, result);

    return result;
}

result = sum(1,2,3,4); // ?

/*
    use ECMAScript's strict mode by adding "use strict";

*/

/*
    If you want to access global variables, then access them via global object (window in browser, global in Node)
*/


var PI = 3.14;
function floorPI() {
    window.PI - window.PI % 0;
}

console.log(PI); // ?
floorPI(); // ?
console.log(PI); // ?

JavaScript, Complete Weirdness

7 - What is "this" ?

/*
    "this" keyword in JavaScript refers to the "owner" of the function.
*/


var person = {
    name: "taner",
    printName: function() {
        return "my name is " + this.name;
    }
};

person.printName(); // my name is taner

/*
    "this" also refers to the element(s) that triggered the event
*/


document.getElementById("user-name").addEventListener("click", function() {
    this.innerHTML = "my name is taner";
});

/*
    rules to define "this" :
    
    - object which the function is called on
    - the object itself when a function called with the "new" operator
    - the owner has been set with "call", "apply" or "bind"
*/

var person = {
    name: "taner",
    printName: function() {
        return "my name is " + this.name;
    }
};

function Dog(name) {
    this.name = name;
}

var otherPerson = {name: "erdi"};

person.printName(); // my name is taner
person["printName"](); // my name is taner

var karabas = new Dog("karabas");
karabas.name; // karabas

person.printName.call(otherPerson); // my name is erdi

var printName = person.printName.bind(otherPerson);
printName(); // my name is erdi

/*
    otherwise, "this" will be the global object or undefined in "strict mode".
*/

Typical JavaScript Interview Questions

Q 1 : Scope : What will be printed in the console ?

(function() {
    var a = b = 5;
})();

console.log(b); // ?

Typical JavaScript Interview Questions

Q 1 : Create "native" methods

/*
    declare a native function over String like "a string".repeat(3)
*/

String.prototype.repeat = String.prototype.repeat || function repeat(times) {
   if (!times) {
        return "";
    }
    return this + repeat(times - 1);
};

Typical JavaScript Interview Questions

Q 3 : Hoisting

function test() {

    // var a;
    console.log(a);
    console.log(foo());

    var a = 1;

    function foo() {
        return 2;
    }
}

test();

/*
    what's the result of the executing code ?
*/

Typical JavaScript Interview Questions

Q 4 : this

var fullName = "John Doe";

var obj = {
    fullName: "Colin Ihrig",
    prop: {
        fullName: "Aurelio De Rosa",
        getFullName: function() {
            return this.fullName;
        }
    }
};

console.log(obj.props.getFullName()); // ?
var test = obj.prop.getFullName; // what is the other way of printing this out as "John Doe" ?
console.log(test()); // ?

Typical JavaScript Interview Questions

Q 5 : call() and apply()

/*
    fix the previous question's issue that the console.log() prints "Aurelio De Rosa".
*/

Essentil JavaScript Interview Questions

Q 1 :

/*
    What is the pitfall with using typeof bar === "object" to determine if "bar" is an object ?
*/

1 - null is considered as object
2 - Arrays are also objects ;)

Essentil JavaScript Interview Questions

Q 2 :

/*
    what is the output of the following code ?
*/

var myObject = {
    foo: "bar",
    func: function() {
        var self = this;

        console.log("this.foo :", this.foo);
        console.log("self.foo :", self.foo);

        (function() {
            console.log("this.foo :", this.foo);
            console.log("self.foo :", self.foo);
        })();
    }
};

myObject.func();

Essentil JavaScript Interview Questions

Q 3 :

/*
    what is the significance of, and reason for, wrapping the entire content of a javascript source file in a function block ?
*/

/*
    this is a common practise employed by many js libraries (jquery, node, etc). This technique creates a closure around the entire contents of the file which, perhaps most importantly, creates a private namespace and thereby helps avoid potential name clashes between different js modules and libraries.

    another feature of this technique is to allow for an easily referencable alias for a global variable. this is often used, for example, in jQuery plugins, jQuery allows you to disable the $ reference to the jQuery namespace, using jQuery.noConflict(). If this has been done, your code can still use $ employing this closure technique, as follows :
*/

(function($) { /* jQuery plugin code referencing $ */ })(jQuery);

Essentil JavaScript Interview Questions

Q 4 :

/*
    What is the significance of the "strict mode" -> "use strict"; ?
*/

1 - easy to debug - shuts down the silent errors
2 - prevent accidental globals - assigning an undeclared value will throw error
3 - eliminates "this" coercion - undefined or null is automatically coerced to the "global" without strict mode.
4 - disallows multiple property names or parameter values - throws error
5 - makes "eval" safer - in strict mode, variables and functions declared inside of an "eval()" statement are not created in the containing scope.
6 - throws error on invalid usage of "delete" - the "delete" operator (used to remove props from objects) can not be used on non-configurable properties of the object. Non-strict code will fail silently when an attempt is made to delete a non-configurable property, whereas strict mode will throw an error.
 

Essentil JavaScript Interview Questions

Q 5 :

/*
    consider the two functions below. will they both return the same thing ? why or why not ?
*/

function f1() {
    return {
        bar: "hello"
    };
}

function f() {
    return
    {
        bar: "hello"
    };
}

console.log(f1()); // ?
console.log(f2()); // ?

Essentil JavaScript Interview Questions

Q 6 :

/*
    what is NaN ? What is its type ? How can you reliably test if a value is equal to NaN ?
*/

console.log(typeof NaN === "number"); // ?
console.log(NaN === NaN); // ?

Essentil JavaScript Interview Questions

Q 7 :

/*
    what will the code below produces ?
*/

console.log(0.1 + 0.2); // ?
console.log(0.1 + 0.2 == 0.3); // ?

Essentil JavaScript Interview Questions

Q 8 :

/*
    what is the order of the numbers logged to console ?
*/

(function() {
    console.log(1);
    setTimeout(function() { console.log(2); }, 1000);
    setTimeout(function() { console.log(3); }, 0};
    console.log(4);
})();

Essentil JavaScript Interview Questions

Q 9 :

/*
    write a sum method which will work properly when invoked using either syntax below ?
*/

console.log(sum(2, 3));
console.log(sum(2)(3));

Essentil JavaScript Interview Questions

Q 10 :

/*
    what will the code below output to the console and why ?
*/

console.log(1 + "2" + "2");
console.log(1 +"2" + "2");
console.log(1 + -"1" + "2");
console.log(+"1" + "1" + "2");
console.log("A" - "B" + "2");
console.log("A" - "B" + 2);

Essentil JavaScript Interview Questions

Q 11:

/*
    the following recursive code will cause a stack overflow if the array is to large. How can you fix this and still retain the recursive pattern ?
*/


var list = readHugeList();

var nextListItem = function() {
    var item = list.pop();
    
    if (item) {
        nextLisItem();
    }
};

Essential JavaScript Interview Questions

Q 12:

/*
    what will be the output of the following code ?
*/


for (var i = 0; i < 5; i++) {
    setTimeout(function() { console.log(i), i * 1000);
}

Essential JavaScript Interview Questions

Q 13:

/*
    what will be the output of the following code ?
*/


var a = {},
    b = {key: "b"},
    c = {key: "c"};

a[b] = 123;
a[c] = 456;

console.log(a[b]); // ?

Essential JavaScript Interview Questions

Q 14:

/*
    what will be the output of the following code ?
*/


(function(x) {
    return (function(y) {
        console.log(x); // ?
    })(2);
})(1);

Essential JavaScript Interview Questions

Q 15:

/*
    what will be the output of the following code ?
*/


var hero = {
    _name: "John Doe",
    getSecretId: function() {
        return this._name;
    }
};

var stoleSecretId = hero.getSecretId;

console.log(stoleSecretId()); // ?
console.log(hero.getSecretId()); // ?

Essential JavaScript Interview Questions

Q 16:

/*
    create a function that, given a DOM element on the page, will visit the element itself and "all" of its descendants (not just immediate children). for each element visited, the function should pass that element to a provided callback function. The arguments to the function should be :
    * a dom element
    * a callback function(that takes a dom element as its argument)
*/

function f(DOMElement, callback) {
    callback(DOMElement);
    Array.prototype.slice.call(DOMElement.querySelectorAll("*"), 0).forEach(function(descendant) {
        f(descendant, callback);
    });
}

deck

By erdi taner gökalp