2011-12-16 7 views
8

変数を関数にキャッシングすることでコードを小さくしようとしていました。たとえば:function.callを変数に保存するときに、 "オブジェクトが関数ではありません"

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

ので、代わりのArray.prototype.slice.call(arguments)を呼び出して、私はちょうどa.call(arguments);を行うことができます。

キャッシングArray.prototype.slice.callでこれをさらに小さくしようとしていましたが、それは機能しませんでした。

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

これは私にTypeError: object is not a functionを与えます。何故ですか?

typeof Array.prototype.slice.callは、期待通りに"function"を返します。

なぜ変数に.callを保存できないのですか?

+0

javascriptエンジンでこのエラーが発生しましたか? –

+0

[Array.prototype.slice.call()をどのように参照していますか?](http://stackoverflow.com/questions/6835315/how-do-you-reference-array-prototype-slice-call) – pimvdb

+0

@DanD .: Chrome 16. –

答えて

7

Function.prototype.callthisとして渡された関数で動作する通常の関数であるというエラーがスローされます今windowにしていないconsoleを指しthisへの呼び出しが含まれています。

callを変数から呼び出すと、thiswindowになりますが、これは機能ではありません。あなたはcall.call(slice, someArray, arg1, arg2)

+0

きちんとしています。 'var a = Array.prototype.slice、b = a.call; b.call(a、arguments) 'を呼び出します。ですから、 '.call'をコピーするときに' this 'を "bind"する方法はありますか? –

+2

@Rocket:https://developer.mozilla.org/ja/JavaScript/Reference/Global_Objects/Function/bind – SLaks

+0

したがって、 'var a = Array.prototype.slice.call.bind(Array.prototype.slice)'?編集:うわー、それは実際に動作します!編集2:ページによると 'varスライス= Function.prototype.call.bind(Array.prototype.slice);'も動作します!ニート! –

5

このお試しください:理由はあなたがこれを行うとき、あなたは私の中で機能xを(割り当てているということである

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

:あなたのような何かをしようとした場合、同じエラーが起こります

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); 
} 

を例log)を変数logに設定します。 しかし機能は、this is not an object

+0

奇妙な、 'var log = console.log; log( 'a');はChrome 16では 'TypeError:Illegal invocation'を返しますが、' var logX = console.log.bind(console); logX( 'a'); '作品:-P –

4

問題を記述する必要が
callは、その所有者(そのthis)が機能することを期待しメソッド(オブジェクトに属し機能)であるということです。 a = Array.prototype.slice.callと書くと、関数はコピーされますが、所有者はコピーされません。

「オブジェクトは機能ではありません」というメッセージは、aは機能ではないと言っているわけではありません。そのthisは機能ではありません。あなたは技術的にはa.call(Array.prototype.slice, arguments)と書くことで説明することができますが、それはあなたが望むものではないことは明らかです!

+0

クール 'a.call(Array.prototype.slice、arguments)'は実際に動作します。私はあなたが関数をコピーしたときに 'this'が正しく参照されると考えました。 –

+2

@Rocket:いいえ - それはできません。なぜなら、 'a.foo = b.foo'や' A.prototype.foo = B.prototype.foo'のような何かをする必要があるからです。あるオブジェクトから別のオブジェクトにメソッドをコピーします。 a.foo()の呼び出しが 'a'ではなく' b'で操作された場合、それはひどく混乱します! – ruakh

関連する問題