// 首先看下原生的js的call()
var obj = {
name: 'Nicholas S.Zakas',
age: 41,
from: 'America',
getName: function (prefix) {
// console.log(prefix + this.name)
return prefix + this.name
}
}
var obj2 = {
name: 'Evan You',
age: '35',
from: 'China'
}
console.log(obj.getName.call(obj2, 'hello, everyone, i am '))
// hello, everyone, i am Evan You
// call()做了什麼?
// 1、將調用call的函數的this指向call函數的第一個參數
// 2、將call()第一個參數後的參數作爲調用call函數的形參
Function.prototype._call = function (context) {
var result
var args = [].slice.apply(arguments, [1])
context.fn = this
result = context.fn(...args)
delete context.fn
return result
}
// 不使用call函數的實現
Function.prototype._newCall = function (context) {
var args = []
var result
for (var i = 1; i < arguments.length; i++) {
args.push('arguments[' + i + ']')
}
context.fn = this
result = eval('context.fn(' + args + ')')
delete context.fn
return result
}
console.log(obj.getName._newCall(obj2, 'hello, everyone, i am '));
// hello, everyone, i am Evan You
// ECMAScript6 的實現
Function.prototype._es6Call = function (context, ...args) {
var result
context.fn = this
result = context.fn(...args)
delete context.fn
return result
}
console.log(obj.getName._es6Call(obj2, 'hello, everyone, i am '));
// hello, everyone, i am Evan You
2020.05.15 修正函數調用call會有返回值