javascriptのthisの針-11
21086 ワード
前言
「javascriptの実行環境-08」では、JavaScriptコードが実行可能なコードを実行すると、対応する実行コンテキストが作成されます.各実行コンテキストには、3つの重要な属性があります.変数オブジェクト(Varable oject,VO) 作用ドメインチェーン this
定義
thisオブジェクトは、動作時に環境バインディングを実行する関数に基づいて、ステートメントの位置よりも関数の呼び出し位置に関係します.thisは、関数呼び出し段階におけるバインディング、すなわちコンテキスト作成を実行する段階において割り当てられ、変数オブジェクトに保存されていると理解できる.
4つのバインディング規則
newコンストラクタバインド、thisは新しく作成されたオブジェクトを指します.
バインディングを表示します.thisは、オブジェクトを転送する方向を指します.
オブジェクトの形で呼び出し、thisは現在のオブジェクトを指します.
デフォルトのバインディングの厳密なモードでは、thisはundefinedにバインドされます.そうでないと、グローバルオブジェクトwindowにバインドされます.
独立呼び出し:thisはwindowを指します.
最後の文を二つのステップに分解して実行します.
締め括りをつける thisは変数オブジェクトの属性の一つで、呼び出し時にバインディングされたもので、ステートメントの位置より関数の呼び出し位置に関係します. 呼び出し位置を見つけ、バインディング規則に従ってthisバインディングを分析する. デフォルトのバインディング厳格モードでは、thisはundefinedにバインドされ、そうでないとグローバルオブジェクトwindowにバインドされます. 思考問題
「javascriptの実行環境-08」では、JavaScriptコードが実行可能なコードを実行すると、対応する実行コンテキストが作成されます.各実行コンテキストには、3つの重要な属性があります.
JavaScript
中のthis
は他の言語とは少し違っています.例えば、Java .net
言語のthis
はコードの実行段階では可変ではなく、JavaScriptのthis
は呼び出し段階でバインディングされています.また、この性質がthis
に大きな柔軟性を与えたからである.すなわち、関数が異なる呼び出し方式であれば、thisの値が異なる可能性がある.定義
thisオブジェクトは、動作時に環境バインディングを実行する関数に基づいて、ステートメントの位置よりも関数の呼び出し位置に関係します.thisは、関数呼び出し段階におけるバインディング、すなわちコンテキスト作成を実行する段階において割り当てられ、変数オブジェクトに保存されていると理解できる.
4つのバインディング規則
newコンストラクタバインド、thisは新しく作成されたオブジェクトを指します.
1 function createPerson(){
2 return new person();
3 }
4 function person() {
5 this.name = "Joel";
6 this.say=function(){
7 console.log(p)
8 console.log('hello' + this.name)
9 }
10 }
11 var p = new person();
12 p.say();
13 console.log(p.name);//Joel
14 console.log(' ')
15 var t=createPerson();
16 t.say();
直接newであろうと、function createPerson関数で帰ってくるオブジェクトであろうと、thisは新しく作成されたオブジェクトを指します.バインディングを表示します.thisは、オブジェクトを転送する方向を指します.
1 //call() apply() bind()
2 window.color = "red";
3 var Obj = { color: "blue" };
4 function sayColor() {
5 console.log(this.color);
6 }
7 sayColor();// red this window
8 sayColor.call(this);//red
9 sayColor.call(window);//red
10 sayColor.call(Obj);// blue this Obj
11 sayColor.apply(Obj);//blue this Obj
12 sayColor.bind(Obj)();//blue this Obj
null/undefinedをthisのバインディングオブジェクトとしてcall/apply/bindに入れば、これらの値は呼び出し時に無視されます.実際に使うのはデフォルトのバインディングルールです.1 function foo() {
2 console.log(this.a)
3 }
4 var a=2;
5 foo.call(null);//2
6 foo.call(undefined);//2
隠士結合オブジェクトの形で呼び出し、thisは現在のオブジェクトを指します.
1 function foo(){
2 console.log(this)//{a: 2, name: "Joel", foo: ƒ}
3 console.log(this.a)//2
4 }
5 var obj={
6 a:2,
7 name:'Joel',
8 foo:foo
9 };
10 obj.foo();
この場合、thisは現在のobjオブジェクトを指しますが、書き方を変えるとthisが失われます. 1 function foo(){
2 console.log(this)//{a: 2, name: "Joel", foo: ƒ}
3 console.log(this.a)//2
4 }
5 var obj={
6 a:2,
7 name:'Joel',
8 foo:foo
9 };
10 obj.foo();
11 //this
12 var t= obj.foo;
13 t(); //window undefined
変数tはこの時保存されています.関数の参照はobjとは関係がないので、ここでthisはwindowを指します.デフォルトのバインディングの厳密なモードでは、thisはundefinedにバインドされます.そうでないと、グローバルオブジェクトwindowにバインドされます.
1 function foo(){
2 console.log(this)//window
3 console.log(this.a)//Joel
4 }
5 var a='Joel';
6 foo();
7
8 //
9 function fo(){
10 'use strict' //
11 console.log(this)//undefined
12 console.log(this.b)// Cannot read property 'b' of undefined
13 }
14 var b='Joel';
15 fo();
以上は基本的なthisバインディング規則であり、new、バインディングが容易であることを示しています.ここでは、デフォルトのバインディングは匿名関数、クローズド、関数をパラメータとしてバインディングしていると誤解しやすいです.独立呼び出し:thisはwindowを指します.
1 var name='Joel',age=12;
2 function say(){
3 function say1(){
4 console.log(this.name);//window
5 function say2(){
6 name+='-l'
7 console.log(this.name);//window
8 }
9 say2()
10 }
11 say1();
12 }
13 say();
14
15 //
16 (function(){
17 console.log(this.name)
18 })()
functionをパラメータとして伝えることは、独立して呼び出すのと同じ原理です. 1 function foo() {
2 console.log(this)//window
3 console.log(this.a)//oops global
4 }
5 function doFoo(fn) {
6 console.log(this);//window
7 fn();// foo()
8 }
9 var obj = {
10 a: 2,
11 foo: foo
12 }
13 var a = 'oops global';
14 doFoo(obj.foo);
同じ理由でsetTimeoutも同じです. 1 var obj = {
2 a: 2,
3 foo: function() {
4 console.log(this);
5 },
6 foo2: function() {
7 console.log(this); //this obj
8 setTimeout(this.foo, 1000); // this window
9 }
10 }
11 var a = 'oops global';
12 obj.foo2();
クローズド中のthis 1 var name = "Joel";
2 var obj = {
3 name: "My object",
4 getName: function() {
5 // var that = this; // getNameFunc() this that
6 return function() {
7 return this.name;
8 };
9 }
10 }
11 console.log(obj.getName()()); // "Joel"
ここではオブジェクトの方法でObj.get Name()を呼び出しますが、getNameのthisはObjを指していますが、戻ってくる匿名関数の中のthisはなぜwindowですか?最後の文を二つのステップに分解して実行します.
1 var t=obj.getName();
2 t();
独立して呼び出しているような感じがしますか?Objのnameにアクセスする必要があれば、thisオブジェクトをキャッシュするだけで、匿名関数にアクセスすることができます.var that=this;注釈を取ればいいです.締め括りをつける
1 var length = 5;
2 var obj = {
3 foo: function (fn) {
4 console.log(this.length); // this => obj
5 fn(); // this => window
6 arguments[0](); // this => arguments
7 var bar = arguments[0];
8 bar(); // this => window
9 },
10 length: 10
11 }
12 var fn = function () {
13 console.log(this.length);
14 }
15 obj.foo(fn);
16 //10, 5, 1, 5