2016-06-22 5 views
0

this、例えば、それが属するオブジェクトを参照:JavaScriptは「この」は機能ブロック

var someObj = { 
    logObj : function() { return this } 
} 

obj.logObj() => someObj 

と機能が目的です。しかし、なぜ関数内のthisが関数ではなくウィンドウを参照しているのですか?例えば、

function someFunc() { return this } 

return someFunc()ませんが、window

+2

これらは全く別の例です。言語があなたの2番目の例のように機能した場合、 'someObj.logObj'は' someObj'ではなくその関数への参照を返します。Javascriptの 'this'への多くのガイドの1つを読んでほしい。 –

+2

someFuncの所有者は、オブジェクトの中に入れなかったのでWindowです。 – Ryan

+0

@ Ryanしかし、関数はオブジェクトです。 –

答えて

0

実際、関数はオブジェクトです。ただし、関数内のステートメントは呼び出されず、関数自体にthisが設定されています。そうすれば、thisは呼び出されたオブジェクトを参照することがなくなり、thisの有用性の多くを排除します。あなたが求めるものを達成する方法があります。 「関数はオブジェクトのメソッドとして呼び出されると、オブジェクトはそのこの値として関数に渡される。」

ECMAScript Specification 4.3.31

関数は、それ自体のメソッドとして呼び出されません。オブジェクトのメソッドとして実行されない関数は、グローバルオブジェクトのメソッドとして呼び出されます( "strict"モードの場合はundefined)。

function test() { 
 
    console.log(this == window); 
 
} 
 

 
var obj = {'test': test}; 
 

 
test(); 
 
window.test(); 
 
obj.test();

あなたが本当に自分自身を参照するための機能でthisのためにしたい場合は、あなたが自分自身の財産としての機能を追加し、またはそのようなapplyとしての機能を使用する必要があります、 callまたはbindであり、thisArgを有する。

function test() { console.log(this) }; 
 

 
test.test = test; 
 

 
test.test(); 
 
test.call(test); 
 
test.apply(test); 
 
test.bind(test)();

+0

で再び参照することができます。私はそれが事実だと知っていますが、私はなぜそれが不思議です。 –

+0

@JaeeunLeeスペックへの参照を求めていますか?それがこのような方法でなければ、「これ」が他のものを参照することは不可能であろう。 「なぜ」が通常間違った質問であるかを尋ねる。 – 4castle

+0

私はうまくいけば理由を説明するように更新しました。 – 4castle

0

コンテキストは、ほとんどの場合、関数が呼び出されるかによって決定されます。関数はオブジェクトのメソッドとして呼び出された場合、これはオブジェクトに設定されている方法は、上で呼び出されます

オブジェクトのインスタンスを作成するために、new演算子を持つ関数を呼び出すときに、同じ原理が適用され
var obj = { 
    foo: function(){ 
     alert(this === obj);  
    } 
}; 

obj.foo(); // true 

。このようにして呼び出されたとき、関数の範囲内で、この値は、新しく作成されたインスタンスに設定されます

function foo(){ 
    alert(this); 
} 

foo() // window 
new foo() // foo 

未結合の関数として呼び出された場合、これはのグローバルコンテキストまたはウィンドウオブジェクトにデフォルト設定されますブラウザ。ただし、strictモードで関数を実行すると、コンテキストはデフォルトでundefinedになります。

+0

' new foo() 'は' foo'をここで警告しません。 'foo'をコンストラクタとしてオブジェクトに警告します。 'foo'に警告する必要がある場合は、' foo.foo = foo;を実行する必要があります。 foo.foo(); ' – 4castle

+0

@ 4castleあなたは私が書いたものを読んでいますか? "このように呼び出されると、関数の範囲内のこの値は新しく作成されたインスタンスに設定されます"。だからあなたのコメントを追加する理由を理解できないのです。 –

0

オブジェクトを作成するには、オブジェクトリテラルを使用する方法と、オブジェクトコンストラクタを使用する方法の少なくとも2つがあります。

thisは、後者のテクニックを使用した場合にのみ発生します。

これは、(あなたの例では、リテラルを使用した)オブジェクトコンストラクタでオブジェクトを作成する方法である:

var objConstructor = function() { 
    this.logObj = function() {return this} 
} 

var obj1 = new objConstructor() 
+0

私の最初の例(someObj)オブジェクトリテラルではありませんか? –

+0

@JaeeunLee私の答えを見てください。それはそれをクリアする。 – 4castle

+0

それが正しく機能しなかった理由です。 Create with Object Literal->これはウィンドウ(または次に近いクロージャ)を参照します。 Create with Objectコンストラクタ - >これはオブジェクトを参照します。 –

関連する問題