// 首先看下原生的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