// 首先看下原生的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()作了什麼? // 一、將調用call的函數的this指向call函數的第一個參數 // 二、將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會有返回值javascript