new
- new被调用后做了什么
- 创建一个空对象,该对象的__proto__属性应该指向new调用的构造函数的prototype
- 将this指向这个空对象
- 执行new调用的构造函数代码块内容
- 根据调用的构造函数是否有返回值判断,如果返回值存在且typeof检测类型为object类型,则返回该结果,如果不存在返回值或者返回值为基础数据类型,则返回创建的对象
- 自己实现的myNew方法
function myNew(ctor, ...rest) {
if (typeof ctor !== 'function') {
throw `${ctor} is not a constructor`
}
const obj = {}
obj.__proto__ = Object.create(ctor.prototype)
const result = ctor.apply(obj, rest)
if (
(typeof result === 'object' && result !== null) ||
typeof result === 'function'
)
return result
return obj
}
apply
- 调用apply函数时,apply函数都做了什么
- 将this指向第一个参数,如果参数不存在,则默认为window
- 执行调用apply方法的函数,apply的第二个参数为数组,里边的内容为函数的参数
Function.prototype.myApply = function (thisArg = window, argArray = []) {
if (typeof this !== 'function') {
throw new Error('Not a function')
}
thisArg.fn = this
const result = thisArg.fn(...argArray)
delete thisArg.fn
return result
}
myApply定义在Function的原型对象上(this指向问题:调用myApply方法的是一个函数,因此this是直接指向函数的)
判断this是否是函数,不是函数就抛出错误
将目标对象thisArg上的fn指向this
调用thisArg.fn,此时fn函数内的this就指向了thisArg
删除thisArg上的fn方法
fn函数结果需要作为myApply的结果进行返回
call
- 调用call函数时,call函数都做了什么
- 将this指向第一个参数,如果参数不存在则默认window
- 第二个及以后的所有参数为调用call函数的函数的参数
Function.prototype.myCall = function (thisArg = window, ...arg) {
if (typeof this !== 'function') {
throw new Error('Not a function')
}
thisArg.fn = this
const result = thisArg.fn(...arg)
delete thisArg.fn
return result
}
将myCall添加到Function的原型对象上
判断当前this是不是一个函数,不是函数就抛出错误
将this绑定到目标对象上,作为目标对象的方法fn
通过thisArg调用fn,此时fn的this就指向了thisArg
删除thisArg上的fn方法
返回函数执行结果作为myCall的执行结果
bind
- 调用bind函数时,bind函数都做了什么
- 第一个参数改变this指向,如果不存在则默认window
- 第二个及以后的参数为调用bind函数的函数的参数,该部分参数会在调用bind方法返回的fBound函数传参前边作为固定参数加入到fBound函数中
Function.prototype.myBind = function (thisArg = window, ...args) {
if (typeof this !== 'function') {
throw new Error('Not a function')
}
let self = this
const fBound = function () {
self.apply(thisArg, [...args, ...arguments])
}
return fBound
}
将myBind添加到Function的原型对象上
判断当前this是不是一个函数,不是函数就抛出错误
定义一个函数fBound,函数内部调用外部this函数的apply方法,参数为目标this对象thisArg和myBind函数传入的参数args和fBound函数的参数合并成的数组,通过此举将调用myBind函数的函数通过apply方法改变了其this指向并执行
返回fBound函数 使用的时候,因为myBind函数返回的是一个函数,需要再次调用,此时就会执行fBound函数,里边的apply函数就会执行,拿到this指向改变的结果