Function.prototype.myCall = function (context, ...args) {
if (!context || context === null) {
context = window
}
// 创造唯一的key值
let fn = Symbol()
context[fn] = this
// 执行上面这句就相当于
/* context[fn] = Product(name, price) {
this.name = name
this.price = price
} */
const res = context[fn](...args)
delete context[fn]
return res
}
function Product(name, price) {
this.name = name
this.price = price
}
function Food(name, price) {
Product.myCall(this, name, price)
//执行完上面那句,此时的this是Food {name: 'cheese', price: 5}
this.category = 'food'
}
console.log(new Food('cheese', 5))
// 第二个参数是传入的数组
const res = [1, [2, 3]]
Function.prototype.myApply = function (context, args) {
if (!context || context === null) {
context = window
}
// 创造唯一key值
let fn = Symbol()
context[fn] = this
// 执行上面这句就相当于 context[fn] = [].concat
// 此时的context是[1, Symbol(): ƒ]
// 执行函数
/* const b = [1, [].concat]
const c = b[1](...[1, 2, 3])
console.log(c)
const res = context[fn](...args)
delete context[fn]
return res
}
console.log([].concat.myApply([1], res))
const numbers = [5, 6, 2, 3, 7]
const max = Math.max.apply(null, numbers)
// 过程类似
const context = [1]
// 把this放到context上
let fn = Symbol()
context[fn] = [].concat
// 执行函数
const a = context[fn](...res)
delete context.fn
console.log(a)
//结果一致
console.log([1].concat(...res))