# 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));
}
```