---
# System prepended metadata

title: js 考題
tags: [' Javascript']

---

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