一、new关键字
1、new调用构造函数时,发生了什么
(1)创建一个新对象
(2)将this指向该新对象
(3)给this添加属性和方法(包括原型)
(4)判断返回引用值
2、模拟new关键字
function myNew(constructor,...args){
let newObj = {}
let res = constructor.apply(newObj,[args])
return (typeof res === 'obj' && typeof res !== null) ? res : newObj
}
二、call、apply、bind
1、作用:可以借用某个方法,不用重复定义。
2、应用场景:
(1)Object.prototype.toString,用于判断数据类型
(2)借用构造函数 constructor stealing,实现给父类构造函数传参并解决原型链继承的’值共享’问题
3、实现call和apply
核心思想:利用this指向规则(方法作为对象属性调用时,this指向该对象)
function myCall(thisArg,...args){
if(typeof thisArg !== 'function') throw new Error('this must be a function')
let originFunc = this,
functionName = synbol();
thisArg[functionName] = this
return thisArg[functionName](...args)
delete thisArg[functionName]
}
function myApply(thisArg,argsArr){
if(typeof thisArg !== 'function') throw new Error('this must be a function')
let originFunc = this,
functionName = synbol();
thisArg[functionName] = this
return thisArg[functionName](...args)
delete thisArg[functionName]
}
4、实现bind
核心思想: 返回一个新函数,执行该函数时,改变this指向。考虑函数prototype属性和使用new关键字调用的情况
function myBind(thisArg, ...formerArgs){
if(typeof thisArg !== 'function') throw new Error ('this must be a funciont')
let originFunction = this
let boundFunction = function (...currentArgs){
let usingNew = this instanceof originFunction;
// 考虑是否用new关键字,是的话,直接返回实例
originFunction.apply(usingNew ? this : thisArg,...formerArgs,...currentArgs)
}
if(originFunction.prototype){
boundFunction.prototype = Object.create(originFunction.prototype)
}
return boundFunction
}