call实现
Function.prototype.newCall = function (context, ...parameter) {
if (typeof context === 'object' || typeof context === 'function') {
context = context || window
} else {
context = Object.create(null) // 创建一个空对象
}
context.fn = this;
let result = context.fn(...parameter);
delete context.fn;
return result
}
let person = {
name: 'zww'
}
function sayHi(age, sex) {
console.log(this.name, age, sex)
}
sayHi.newCall(person, 22, '男')
apply实现
Function.prototype.newApply = function (context, paramter) {
if (typeof context === 'object' || typeof context === 'function') {
context = context || window
} else {
context = Object.create(null) // 创建一个空对象
}
context.fn = this;
let result = context.fn(...paramter);
delete context.fn
return result
}
let person = {
name: 'zww'
}
function sayHi(age, sex) {
console.log(this.name, age, sex)
}
sayHi.newApply(person, [22, '男'])
bind 的实现对比其他两个函数略微地复杂了一点,因为 bind 需要返回一个函数,需要判断一些边界问题。bind 返回了一个函数,对于函数来说有两种方式调用,一种是直接调用,一种是通过 new 的方式。对于 new 的情况来说,不会被任何方式改变 this,所以对于这种情况我们需要忽略传入的 this。
Function.prototype.newBind = function (context, ...innerArgs) {
if (typeof context === 'object' || typeof context === 'function') {
context = context || window
} else {
context = Object.create(null)
}
var _this = this
return function F(...finallyArgs) {
if (this instanceof F) { // new 的方式调用
return new _this(...innerArgs, ...finallyArgs)
}
return _this.call(context, ...innerArgs, ...finallyArgs)
}
}
let person = {
name: 'zww'
}
function sayHi(age, sex) {
console.log(this.name, age, sex)
}
let personSayHi = sayHi.newBind(person, 22)
new personSayHi('男')