Silencer-1984 / Summary-of-front-end-work

总结包括一切关于前端学习的东西,面试、学英语、开发规范
0 stars 0 forks source link

单独实现call,bind,apply,new,instanceof #12

Open Silencer-1984 opened 3 years ago

Silencer-1984 commented 3 years ago

call的实现

// 首先 context 为可选参数,如果不传的话默认上下文为 window
// 接下来给 context 创建一个 fn 属性,并将值设置为需要调用的函数
// 因为 call 可以传入多个参数作为调用函数的参数,所以需要将参数剥离出来
// 然后调用函数并将对象上的函数删除

Function.prototype.myCall = function (content) {
  if (typeof this !== "function") {
    throw new TypeError("Error");
  }
  content = content || window;
  let args = [].slice.call(arguments, 1);
  content.fn = this;
  const result = content.fn(...args);
  delete content.fn;
  return result;
};

apply

Function.prototype.myApply = function (content) {
  if (typeof this !== "function") {
    throw new TypeError("Error");
  }
  content = content || window;
  content.fn = this;
  let = result;
  if (arguments[1]) {
    result = content.fn(...arguments[1]);
  } else {
    result = content.fn();
  }
  delete content.fn;
  return result;
};

bind()函数会创建一个新的绑定函数bound function,BF)。绑定函数是一个 exotic function object(怪异函数对象,ECMAScript 2015 中的术语),它包装了原函数对象。调用绑定函数通常会导致执行包装函数绑定函数具有以下内部属性:

当调用绑定函数时,它调用[[BoundTargetFunction]]上的内部方法[[Call]],就像这样Call(boundThis,args)。其中,boundThis[[BoundThis]]args[[BoundArguments]]加上通过函数调用传入的参数列表。 绑定函数也可以使用new运算符构造,它会表现为目标函数已经被构建完毕了似的。提供的this值会被忽略,但前置参数仍会提供给模拟函数。

var person = new Otaku('Kevin', '18');

console.log(person.name) // Kevin console.log(person.habit) // Games console.log(person.strength) // undefined console.log(person.age) // undefined

```javascript
// 注意:当new的构造函数有返回内容且内容为一个对象时。实例只会继承返回对象的属性。下面做了判断。
function create() {
  let obj = {};
  let con = [].shift.call(arguments);
  obj.__proto__ = con.prototype;
  let result = con.apply(obj, arguments);
  return result instanceof Object ? result : obj;
}

instanceof

function myInstanceof (left, right) {
    const prototype = right.prototype
    let left = left.__proto__
    while(true){
        if(left===undefined || left===null){
            return false
        }
        if(left === prototype){
            return true
        }
        left = left.__proto__
    }
}