# test for js ## prototype chain ### Question ```javascript= /** * @param {*} obj * @param {*} classFunction * @return {boolean} */ var checkIfInstanceOf = function(obj, classFunction) { }; console.assert(checkIfInstanceOf(new Date(), Date), 'should be true'); class Animal {}; class Dog extends Animal {}; console.assert(checkIfInstanceOf(new Dog(), Animal), 'should be true'); console.assert(checkIfInstanceOf(Date, Date)==false, 'should be false'); console.assert(checkIfInstanceOf(5, Number), 'should be true'); ``` ### Quset link https://onecompiler.com/javascript/3zwue2hub ### Possible answer ```typescript= /** * @param {*} obj * @param {*} classFunction * @return {boolean} */ var checkIfInstanceOf = function(obj, classFunction) { if (obj === null || obj === undefined || typeof classFunction !== 'function') { return false } // resolve prototype chain let currentPrototype = Object.getPrototypeOf(obj); while(currentPrototype !== null) { if (currentPrototype === classFunction.prototype) { return true; } currentPrototype = Object.getPrototypeOf(currentPrototype); } return false; }; ``` ## this concept ### Question ```javascript= /** * @param {Object} context * @param {Array} args * @return {null|boolean|number|string|Array|Object} */ Function.prototype.callPolyfill = function(context, ...args) { // attach context with default this } function increment() { this.count++; return this.count; } console.assert(increment.callPolyfill({count:1})==2, 'should be 2') fn = function add(b) { return this.a + b; } console.assert(fn.callPolyfill({"a": 5}, 7)==12, 'should be 12') fn2 = function tax(price, taxRate) { return `The cost of the ${this.item} is ${price * taxRate}`; } console.assert(fn2.callPolyfill({"item": "burger"}, 10, 1.1)=='The cost of the burger is 11', 'result should be \"The cost of the burger is 11\"'); ``` ### Question Link https://onecompiler.com/javascript/3zwud9j4w ### Possible Answer ```javascript= /** * @param {Object} context * @param {Array} args * @return {null|boolean|number|string|Array|Object} */ Function.prototype.callPolyfill = function(context, ...args) { // attach context with default this // return this.bind(context)(...args); // return this.apply(context, args); const uniqueId = Symbol(); context[uniqueId] = this; console.log(context); const res = context[uniqueId](...args); delete context[uniqueId]; return res; } /** * function increment() { this.count++; return this.count; } * increment.callPolyfill({count: 1}); // 2 */ ``` ## Timer execution and Closure ### Question Q1:What is the result ? Q2: What if try to print out 0,1,2? ```javascript= for (var i = 0; i < 3; i++) { setTimeout(()=>{ console.log(i) }); } ``` ### Question Link https://onecompiler.com/javascript/3zwufv82q ### Answer Q1: because the main thread first execution main stack after stack call finish call the micraTask , then microTask Q2: 1. Possible anwser: use closure ```javascript= for (var i = 0; i < 3; i++) { setTimeout(((val)=>()=>{ console.log(val) })(i)); } ``` 2. lexical scope variable with let ```javascript= for (let i = 0; i < 3; i++) { setTimeout(()=>conosle.log(i)); } ```