function Symbol (obj) {
// 保证传入对象中 新建的这个方法是唯一 key
let x = (Math.random() + new Date().getTime()).toString(32).slice(0, 8)
// 利用时间戳 保证 X 值为 obj 中的唯一 key 值
if (obj.hasOwnProperty(x)) {
// hasOwnProperty 对象自带方法, 判断传入值在已有对象中是否已存在
return mySymbol(obj) //递归调用
} else {
return x
}
}
Function.prototype.MyBind = function (context) {
// Function.prototype.MyCall = function (context) {
// context就是demo中的Person1
// 必须此时调用MyCall的函数是say方法,
// 那么我们只需要在context上扩展一个say方法指向调用MyCall的say方法这样this
context = context || window
let fn = Symbol(context) // 保证 fn 为 context 中为一值
context[fn] = this //Mycall里边的this就是我们虚拟的say方法
let arg = [...arguments].slice(1)
// context[fn](...arg) // MyCall // call 可以传入很多参数
context[fn](arg) // MyBind // bind 传入的第二各参数为为数组
delete context[fn] // 最后删除 新增到传入对象中的方法
}
let Person = {
name: 'Tom',
say() {
console.log(this)
console.log(`我叫${this.name}`)
}
}
Person1 = { name: 'Tom11' }
// Person.say.call(Person1) // 原 call 方法
// 测试 // Person.say.MyCall(Person1,1,5,8) //我叫Tom1
Person.say.MyBind(Person1, [1, 5, 8]) //我叫Tom1