其他分享
首页 > 其他分享> > module1-04-实现 new、apply、call、bind 的底层逻辑

module1-04-实现 new、apply、call、bind 的底层逻辑

作者:互联网

实现 new、apply、call、bind 的底层逻辑

一、new

function Person() {
  this.name = 'Jack';
}
var p = new Person();
console.log(p.name)  // Jack

(1)new在生成实例过程中分几个步骤呢?

(2)如果去掉new会怎么样的?

function Person(){
 this.name = 'Jack';
}
var p = Person();
console.log(p) // undefined
console.log(name) // Jack
console.log(p.name) // 'name' of undefined

(3)当函数有返回值的话呢?

function Person(){
  this.name = 'Jack';
  return {age: 18}
}
var p = new Person();
console.log(p)  // {age: 18}
console.log(p.name) // undefined
console.log(p.age) // 18
function Person(){
  this.name = 'Jack';
  return 'tom';
}
var p = new Person();
console.log(p)  // {name: 'Jack'}
console.log(p.name) // Jack

(4)自己实现的new

function _new(ctor, ...args) {
 if (typeof ctor !== 'function') throw 'ctor must be a function';; // 必须为一个函数
   
 let obj = {}; // 创建一个空对象
 Reflect.setPrototypeOf(obj, ctor.prototype); // 绑定原型
 let res = ctor.apply(obj, args); // 这里做了两件事, 1. 获取ctor的返回值 2. 将ctor的this指向obj并执行里面的代码,包括往this添加属性

 return typeof res === 'function' || (typeof res === 'object' && typeof res !== 'null') ? res : obj;
} // 判断是否为一个对象

二、apply & call & bind 原理介绍

func.call(thisArg, param1, param2, ...)
func.apply(thisArg, [param1,param2,...])
func.bind(thisArg, param1, param2, ...)
let a = {
 name: 'jack',
 getName: function(msg) {
   return msg + this.name;
}
}
let b = {
 name: 'lily'
}
console.log(a.getName('hello~'));  // hello~jack
console.log(a.getName.call(b, 'hi~'));  // hi~lily
console.log(a.getName.apply(b, ['hi~']))  // hi~lily
let name = a.getName.bind(b, 'hello~');
console.log(name());  // hello~lily

(1)应用场景

(2)apply和call的实现

Function.prototype.myCall = function (content, ...args) {
 var content = content || window; // 没有制定content则默认window,使用var是因为要绑定到全局中
 content.fn = this; // 使要指向的对象添加一个fn方法
 let result = eval('content.fn(...args)'); // 使用eval调用该方法
 delete content.fn; // 完成之后删除引用
 return result;
}
Function.prototype.myApply = function (content, args) {
 var content = content || window;
 content.fn = this;
 let result = eval('content.fn(args)');
 delete content.fn;
 return result;
}
// 同上

(3)bind的实现

Function.prototype.myBind = function (content, ...args) {
  if (typeof this !== 'function') throw 'this must be a function'; // 必须是一个函数
  const self = this; // 将这个函数的this指向保存在self
  const fbind = function () {
    self.apply(this instanceof self ? this : content, Array.prototype.concat.apply(args, arguments));
  } // 定义的这个新函数里面执行的就是一个apply, self中的函数执行,然后在这过程中改变this指向为content
  if (this.prototype) Reflect.setPrototypeOf(fbind, this.prototype); // 将原型对象赋予给fbind
  return fbind;
}

(4)总结

标签:function,name,04,bind,module1,content,new,apply,log
来源: https://www.cnblogs.com/lezaizhu/p/14455034.html