我试图在javascript中执行call方法的本地实现。在这里,我们需要处理在调用函数和其他参数中传递的对象。我使用eval()
方法处理其他参数。有没有有效的方法来执行本机call()
函数实现。这是我的代码
var name = {
name: "JavaScript",
version: "6",
}
function printName(location, district){
alert(this.name + ", " + this.version + ", " + location + ", " + district);
}
Function.prototype.myCall = function(...args){
var param = args.slice(1),
paramLength = param.length,
paramString = "JSONarg.myFun(";
for(var i = 1; i <= paramLength; i++){
paramString += "args["+i+"],";
}
paramString += ")";
if(typeof this != 'function'){
throw new Error(this + " is not a Function");
}
var JSONarg = {
...args[0],
myFun: this
}
return eval(paramString);
}
printName.myCall(name, "Chrome", "browser");
答案 0 :(得分:1)
没有通话。
Function.prototype.myCall = function(context, ...args){
this.apply(context, args)
}
但是我没有理由
答案 1 :(得分:0)
您的 call
方法实现似乎是 ES3 版本,因为您创建了一个 params 列表字符串并使用 eval
来执行该函数。但是你也在这里使用了rest params,证明浏览器支持ES6。所以我们可以使用扩展语法让事情变得更简单。
总之,如果你非要用ES3来实现方法,你可以这样做:
// ES3 viersion
Function.prototype.myCall = function(thisArg){
if(typeof this != 'function'){
throw new Error('the caller must be a function')
}
if(thisArg === null || thisArg === undefined){
thisArg = window
} else {
thisArg = new Object(thisArg)
}
const args = []
for(var i = 1;i < arguments.length;i ++){
args.push('arguments[' + i + ']')
}
thisArg.fn = this
const res = eval('thisArg.fn(' + args + ')')
delete thisArg.fn
return res
}
上面的版本与您的相似。但是如果允许使用 ES6,你可以像这样更高效地进行:
// ES6 verison
Function.prototype.myCall = function(thisArg,...args){
if(typeof this != 'function'){
throw new Error('the caller must be a function')
}
if(thisArg === null || thisArg === undefined){
thisArg = window
} else {
thisArg = new Object(thisArg)
}
thisArg.fn = this
const res = thisArg.fn(...args)
delete thisArg.fn
return res
}
然而,值得注意的是这两个版本都不是标准实现。