/**
* @description 模拟实现 call
* 1. 改变 this 指向
* 2. 执行函数
*/
// 用法
var foo = {
value: 1
}
function bar() {
console.log(this.foo)
}
bar.call(foo) // 把 bar 的 this 绑定到 foo 上, 只要将bar函数变成foo的属性即可使用foo的this,用完删除
// 变成这样就 OK 啦
var foo = {
value: 1,
bar: function() {
console.log(this.value)
}
}
/**
* 模拟实现第一步
* 1. foo.fn = bar
* 2. foo.fn()
* 3. delete foo.fn()
*/
Function.prototype.mycall = function(context) {
context.fn = this
context.fn()
delete context.fn
}
/**
* 模拟实现第二步
* call 函数可以传递参数并执行, 参数不确定
* var foo = {
value: 1
}
function bar (name, age) {
console.log(name, age, this.value)
}
bar.call(foo, 'agren', 26)
*/
Function.prototype.mycall = function(context) {
var context = context || window
context.fn = this
var args = [...arguments].slice(1) // 拿到第一个到最后一个的参数
var result = context.fn(...args)
delete context.fn
return result
}
/**
* @description 模拟实现 apply 与 call 类似,只不过,只有两个参数,第二个参数是数组
*/
Function.prototype.myApply = function(context = window) {
context.fn = this
var result
if (arguments[1]) {
result = context.fn(...arguments[1]) // 还是只取第一个到最后一个的参数
} else {
result = context.fn()
}
delete context.fn
return result
}
/**
* @description 模拟实现 bind 方法 与上面两个类似
* 1. 设置this 为执行的值,并会返回函数
* 2. 调用函数时,将给定参数列表,作为原函数参数列表的千若干项
*/
// bind 第一步
Function.prototype.myBind = function(...rest1) {
const self = this
const context = rest1.shift() // 拿到第一个参数
return function(...rest2) {
return self.apply(context, [...rest1, ...rest2])
}
}
网友评论