<script>
/**
* call方法
* 第一个参数为null或者undefined时,this指向全局对象window,
* 值为原始值的指向该原始值的自动包装对象,如 String、Number、Boolean
*/
Function .prototype.myCall = function(context,...args) {
if(context === undefined || context === null) {
context = window
}
if(typeof context !== 'undefined' && typeof context !== 'function' && typeof context !== 'object') {
context = new Object(context)
}
const fn = Symbol() //声明一个Symbol类型的属性,表示是一个唯一的属性,防止被其他同名属性覆盖
context[fn] = this // this指向调用call方法的那个对象
const result = context[fn](...args) // 执行
delete context[fn] // 删除fn属性
return result
}
function cc() {
console.log(this.name)
}
obj = {
name:'xx'
}
cc.myCall(obj)
/**
* cc.myCall(obj) -> 首先this指向,改为obj
* 所以myCall函数中context[fn] = this,在上面的函数中,this指向的是function cc()
* 然后context[fn]() ->可以当成 context.fn()
* 需要理解的是 context[fn]() 等同于 cc.myCall(obj),而myCall函数第一个参数就是函数内部的this
* cc.myCall(obj) 就相当于
* obj.cc = cc 声明一个cc属性,将cc函数赋值给这个属性
* obj.cc() 调用
*/
</script>