可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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!