“object is not a function” when saving function.call to a variable

匿名 (未验证) 提交于 2019-12-03 01:39:01

问题:

I was trying to make my code smaller by caching functions to variables. For example:

function test(){    var a = Array.prototype.slice,    b = a.call(arguments);    // Do something    setTimeout(function(){      var c = a.call(arguments);      // Do something else    }, 200); } 

So instead of calling Array.prototype.slice.call(arguments), I can just do a.call(arguments);.

I was trying to make this even smaller by caching Array.prototype.slice.call, but that wasn't working.

function test(){    var a = Array.prototype.slice.call,    b = a(arguments);    // Do something    setTimeout(function(){      var c = a(arguments);      // Do something else    }, 200); } 

This gives me TypeError: object is not a function. Why is that?

typeof Array.prototype.slice.call returns "function", like expected.

Why can't I save .call to a variable (and then call it)?

回答1:

Function.prototype.call is an ordinary function that operates on the function passed as this.

When you call call from a variable, this becomes window, which is not a function.
You need to write call.call(slice, someArray, arg1, arg2)



回答2:

Try this:

function test(){    var a = function(args){        return Array.prototype.slice.call(args);    };    b = a(arguments);    // Do something    setTimeout(function(){      var c = a(arguments);      // Do something else    }, 200); } 

The same error will happen if you try doing something like:

var log = console.log; log("Hello"); 

The reason is that when you do this you are assigning the function x (in my example log) to the variable log. BUT the function contains a call to this which now refers to window and not to console, which then throws an error that this is not an object



回答3:

The problem is that call is a method (a function that belongs to an object) that expects its owner (its this) to be a function. When you write a = Array.prototype.slice.call, you're copying the function, but not the owner.

The "object is not a function" message isn't saying that a isn't a function, it's saying that its this isn't a function. You could technically achieve what you describe by writing a.call(Array.prototype.slice, arguments), but obviously that's not what you want!



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!