" />

            国产精品爱久久久久久久小说,女人扒开腿让男人桶到爽 ,亚洲欧美国产双大乳头,国产成人精品综合久久久久,国产精品制服丝袜无码,免费无码精品黄av电影,黑色丝袜无码中中文字幕,乱熟女高潮一区二区在线

            JavaScript必須掌握的基礎 ---> this

            2020-5-30    seo達人

            this

            this是我們在書寫代碼時最常用的關鍵詞之一,即使如此,它也是JavaScript最容易被最頭疼的關鍵詞。那么this到底是什么呢?


            如果你了解執(zhí)行上下文,那么你就會知道,其實this是執(zhí)行上下文對象的一個屬性:


            executionContext = {

               scopeChain:[ ... ],

               VO:{

                   ...

               },

               this:  ?

            }

            執(zhí)行上下文中有三個重要的屬性,作用域鏈(scopeChain)、變量對象(VO)和this。


            this是在進入執(zhí)行上下文時確定的,也就是在函數(shù)執(zhí)行時才確定,并且在運行期間不允許修改并且是永久不變的


            在全局代碼中的this

            在全局代碼中this 是不變的,this始終是全局對象本身。


            var a = 10;

            this.b = 20;

            window.c = 30;


            console.log(this.a);

            console.log(b);

            console.log(this.c);


            console.log(this === window) // true

            // 由于this就是全局對象window,所以上述 a ,b ,c 都相當于在全局對象上添加相應的屬性

            如果我們在代碼運行期嘗試修改this的值,就會拋出錯誤:


            this = { a : 1 } ; // Uncaught SyntaxError: Invalid left-hand side in assignment

            console.log(this === window) // true

            函數(shù)代碼中的this

            在函數(shù)代碼中使用this,才是令我們最容易困惑的,這里我們主要是對函數(shù)代碼中的this進行分析。


            我們在上面說過this的值是,進入當前執(zhí)行上下文時確定的,也就是在函數(shù)執(zhí)行時并且是執(zhí)行前確定的。但是同一個函數(shù),作用域中的this指向可能完全不同,但是不管怎樣,函數(shù)在運行時的this的指向是不變的,而且不能被賦值。


            function foo() {

               console.log(this);

            }


            foo();  // window

            var obj={

               a: 1,

               bar: foo,

            }

            obj.bar(); // obj

            函數(shù)中this的指向豐富的多,它可以是全局對象、當前對象、或者是任意對象,當然這取決于函數(shù)的調(diào)用方式。在JavaScript中函數(shù)的調(diào)用方式有一下幾種方式:作為函數(shù)調(diào)用、作為對象屬性調(diào)用、作為構(gòu)造函數(shù)調(diào)用、使用apply或call調(diào)用。下面我們將按照這幾種調(diào)用方式一一討論this的含義。


            作為函數(shù)調(diào)用

            什么是作為函數(shù)調(diào)用:就是獨立的函數(shù)調(diào)用,不加任何修飾符。


            function foo(){

               console.log(this === window); // true

               this.a = 1;

               console.log(b); // 2

            }

            var b = 2;

            foo();

            console.log(a); // 1

            上述代碼中this綁定到了全局對象window。this.a相當于在全局對象上添加一個屬性 a 。


            在嚴格模式下,獨立函數(shù)調(diào)用,this的綁定不再是window,而是undefined。


            function foo() {

               "use strict";

               console.log(this===window); // false

               console.log(this===undefined); // true

            }

            foo();

            這里要注意,如果函數(shù)調(diào)用在嚴格模式下,而內(nèi)部代碼執(zhí)行在非嚴格模式下,this 還是會默認綁定為 window。


            function foo() {

               console.log(this===window); // true

            }



            (function() {

               "use strict";

               foo();

            })()

            對于在函數(shù)內(nèi)部的函數(shù)獨立調(diào)用 this 又指向了誰呢?


            function foo() {

               function bar() {

                   this.a=1;

                   console.log(this===window); // true

               }

               bar()

            }

            foo();

            console.log(a); // 1

            上述代碼中,在函數(shù)內(nèi)部的函數(shù)獨立調(diào)用,此時this還是被綁定到了window。


            總結(jié):當函數(shù)作為獨立函數(shù)被調(diào)用時,內(nèi)部this被默認綁定為(指向)全局對象window,但是在嚴格模式下會有區(qū)別,在嚴格模式下this被綁定為undefined。


            作為對象屬性調(diào)用

            var a=1;

            var obj={

               a: 2,

               foo: function() {

                   console.log(this===obj); // true

                   console.log(this.a); // 2

               }

            }

            obj.foo();

            上述代碼中 foo屬性的值為一個函數(shù)。這里稱 foo 為 對象obj 的方法。foo的調(diào)用方式為 對象 . 方法 調(diào)用。此時 this 被綁定到當前調(diào)用方法的對象。在這里為 obj 對象。


            再看一個例子:


            var a=1;

            var obj={

               a: 2,

               bar: {

                   a: 3,

                   foo: function() {

                       console.log(this===bar); // true

                       console.log(this.a); // 3

                   }

               }

            }

            obj.bar.foo();

            遵循上面說的規(guī)則 對象 . 屬性 。這里的對象為 obj.bar 。此時 foo 內(nèi)部this被綁定到了 obj.bar 。 因此 this.a 即為 obj.bar.a 。


            再來看一個例子:


            var a=1;

            var obj={

               a: 2,

               foo: function() {

                   console.log(this===obj); // false

                   console.log(this===window); // true

                   console.log(this.a); // 1

               }

            }


            var baz=obj.foo;

            baz();

            這里 foo 函數(shù)雖然作為對象obj 的方法。但是它被賦值給變量 baz 。當baz調(diào)用時,相當于 foo 函數(shù)獨立調(diào)用,因此內(nèi)部 this被綁定到 window。


            使用apply或call調(diào)用

            apply和call為函數(shù)原型上的方法。它可以更改函數(shù)內(nèi)部this的指向。


            var a=1;

            function foo() {

               console.log(this.a);

            }

            var obj1={

               a: 2

            }

            var obj2={

               a: 3

            }

            var obj3={

               a: 4

            }

            var bar=foo.bind(obj1);

            bar();// 2  this => obj1

            foo(); // 1  this => window

            foo.call(obj2); // 3  this => obj2

            foo.call(obj3); // 4  this => obj3

            當函數(shù)foo 作為獨立函數(shù)調(diào)用時,this被綁定到了全局對象window,當使用bind、call或者apply方法調(diào)用時,this 被分別綁定到了不同的對象。


            作為構(gòu)造函數(shù)調(diào)用

            var a=1;

            function Person() {

               this.a=2;  // this => p;

            }

            var p=new Person();

            console.log(p.a); // 2

            上述代碼中,構(gòu)造函數(shù) Person 內(nèi)部的 this 被綁定為 Person的一個實例。


            總結(jié):


            當我們要判斷當前函數(shù)內(nèi)部的this綁定,可以依照下面的原則:


            函數(shù)是否在是通過 new 操作符調(diào)用?如果是,this 綁定為新創(chuàng)建的對象

            var bar = new foo();     // this => bar;

            函數(shù)是否通過call或者apply調(diào)用?如果是,this 綁定為指定的對象

            foo.call(obj1);  // this => obj1;

            foo.apply(obj2);  // this => obj2;

            函數(shù)是否通過 對象 . 方法調(diào)用?如果是,this 綁定為當前對象

            obj.foo(); // this => obj;

            函數(shù)是否獨立調(diào)用?如果是,this 綁定為全局對象。

            foo(); // this => window

            DOM事件處理函數(shù)中的this

            1). 事件綁定


            <button id="btn">點擊我</button>


            // 事件綁定


            function handleClick(e) {

               console.log(this); // <button id="btn">點擊我</button>

            }

                   document.getElementById('btn').addEventListener('click',handleClick,false);  //   <button id="btn">點擊我</button>

                   

            document.getElementById('btn').onclick= handleClick; //  <button id="btn">點擊我</button>

            根據(jù)上述代碼我們可以得出:當通過事件綁定來給DOM元素添加事件,事件將被綁定為當前DOM對象。


            2).內(nèi)聯(lián)事件


            <button onclick="handleClick()" id="btn1">點擊我</button>

            <button onclick="console.log(this)" id="btn2">點擊我</button>


            function handleClick(e) {

               console.log(this); // window

            }


            //第二個 button 打印的是   <button id="btn">點擊我</button>

            我認為內(nèi)聯(lián)事件可以這樣理解:


            //偽代碼


            <button onclick=function(){  handleClick() } id="btn1">點擊我</button>

            <button onclick=function() { console.log(this) } id="btn2">點擊我</button>

            這樣我們就能理解上述代碼中為什么內(nèi)聯(lián)事件一個指向window,一個指向當前DOM元素。(當然瀏覽器處理內(nèi)聯(lián)事件時并不是這樣的)


            定時器中的this

            定時器中的 this 指向哪里呢?


            function foo() {

               setTimeout(function() {

                   console.log(this); // window

               },1000)

            }

            foo();  

            再來看一個例子


            var name="chen";

            var obj={

               name: "erdong",

               foo: function() {

                   console.log(this.name); // erdong

                   setTimeout(function() {

                       console.log(this.name); // chen

                   },1000)

               }

            }

            obj.foo();

            到這里我們可以看到,函數(shù) foo 內(nèi)部this指向為調(diào)用它的對象,即:obj 。定時器中的this指向為 window。那么有什么辦法讓定時器中的this跟包裹它的函數(shù)綁定為同一個對象呢?


            1). 利用閉包:


            var name="chen";

            var obj={

               name: "erdong",

               foo: function() {

                   console.log(this.name) // erdong

                   var that=this;

                   setTimeout(function() {

                       // that => obj

                       console.log(that.name); // erdong

                   },1000)

               }

            }

            obj.foo();

            利用閉包的特性,函數(shù)內(nèi)部的函數(shù)可以訪問含義訪問當前詞法作用域中的變量,此時定時器中的 that 即為包裹它的函數(shù)中的 this 綁定的對象。在下面我們會介紹利用 ES6的箭頭函數(shù)實現(xiàn)這一功能。


            當然這里也可以適用bind來實現(xiàn):


            var name="chen";

            var obj={

               name: "erdong",

               foo: function() {

                   console.log(this.name); // erdong

                   setTimeout(function() {

                       // this => obj

                       console.log(this.name); // erdong

                   }.bind(this),1000)

               }

            }

            obj.foo();

            被忽略的this

            如果你把 null 或者 undefined 作為 this 的綁定對象傳入 call 、apply或者bind,這些值在調(diào)用時會被忽略,實例 this 被綁定為對應上述規(guī)則。


            var a=1;

            function foo() {

               console.log(this.a); // 1  this => window

            }

            var obj={

               a: 2

            }

            foo.call(null);

            var a=1;

            function foo() {

               console.log(this.a); // 1  this => window

            }

            var obj={

               a: 2

            }

            foo.apply(null);

            var a=1;

            function foo() {

               console.log(this.a); // 1  this => window

            }

            var obj={

               a: 2

            }

            var bar = foo.bind(null);

            bar();

            bind 也可以實現(xiàn)函數(shù)柯里化:


            function foo(a,b) {

               console.log(a,b); // 2  3

            }

            var bar=foo.bind(null,2);

            bar(3);

            更復雜的例子:


            var foo={

               bar: function() {

                   console.log(this);

               }

            };


            foo.bar(); // foo

            (foo.bar)(); // foo


            (foo.bar=foo.bar)(); // window

            (false||foo.bar)();  // window

            (foo.bar,foo.bar)();  // window

            上述代碼中:


            foo.bar()為對象的方法調(diào)用,因此 this 綁定為 foo 對象。


            (foo.bar)() 前一個() 中的內(nèi)容不計算,因此還是 foo.bar()


            (foo.bar=foo.bar)() 前一個 () 中的內(nèi)容計算后為 function() { console.log(this); } 所以這里為匿名函數(shù)自執(zhí)行,因此 this 綁定為 全局對象 window


            后面兩個實例同上。


            這樣理解會比較好:


            (foo.bar=foo.bar)  括號中的表達式執(zhí)行為 先計算,再賦值,再返回值。

            (false||foo.bar)()    括號中的表達式執(zhí)行為 判斷前者是否為 true ,若為true,不計算后者,若為false,計算后者并返回后者的值。

            (foo.bar,foo.bar)   括號中的表達式之行為分別計算 “,” 操作符兩邊,然后返回  “,” 操作符后面的值。

            箭頭函數(shù)中的this

            箭頭函數(shù)時ES6新增的語法。


            有兩個作用:


            更簡潔的函數(shù)

            本身不綁定this

            代碼格式為:


            // 普通函數(shù)

            function foo(a){

               // ......

            }

            //箭頭函數(shù)

            var foo = a => {

               // ......

            }


            //如果沒有參數(shù)或者參數(shù)為多個


            var foo = (a,b,c,d) => {

               // ......

            }

            我們在使用普通函數(shù)之前對于函數(shù)的this綁定,需要根據(jù)這個函數(shù)如何被調(diào)用來確定其內(nèi)部this的綁定對象。而且常常因為調(diào)用鏈的數(shù)量或者是找不到其真正的調(diào)用者對 this 的指向模糊不清。在箭頭函數(shù)出現(xiàn)后其內(nèi)部的 this 指向不需要再依靠調(diào)用的方式來確定。


            箭頭函數(shù)有幾個特點(與普通函數(shù)的區(qū)別)


            箭頭函數(shù)不綁定 this 。它只會從作用域鏈的上一層繼承 this。

            箭頭函數(shù)不綁定arguments,使用reset參數(shù)來獲取實參的數(shù)量。

            箭頭函數(shù)是匿名函數(shù),不能作為構(gòu)造函數(shù)。

            箭頭函數(shù)沒有prototype屬性。

            不能使用 yield 關鍵字,因此箭頭函數(shù)不能作為函數(shù)生成器。

            這里我們只討論箭頭函數(shù)中的this綁定。


            用一個例子來對比普通函數(shù)與箭頭函數(shù)中的this綁定:


            var obj={

               foo: function() {

                   console.log(this); // obj

               },

               bar: () => {

                   console.log(this); // window

               }

            }

            obj.foo();

            obj.bar();

            上述代碼中,同樣是通過對象 . 方法調(diào)用一個函數(shù),但是函數(shù)內(nèi)部this綁定確是不同,只因一個數(shù)普通函數(shù)一個是箭頭函數(shù)。


            用一句話來總結(jié)箭頭函數(shù)中的this綁定:


            個人上面說的它會從作用域鏈的上一層繼承 this ,說法并不是很正確。作用域中存放的是這個函數(shù)當前執(zhí)行上下文與所有父級執(zhí)行上下文的變量對象的集合。因此在作用域鏈中并不存在 this 。應該說是作用域鏈上一層對應的執(zhí)行上下文中繼承 this 。


            箭頭函數(shù)中的this繼承于作用域鏈上一層對應的執(zhí)行上下文中的this


            var obj={

               foo: function() {

                   console.log(this); // obj

               },

               bar: () => {

                   console.log(this); // window

               }

            }

            obj.bar();

            上述代碼中obj.bar執(zhí)行時的作用域鏈為:


            scopeChain = [

               obj.bar.AO,

               global.VO

            ]

            根據(jù)上面的規(guī)則,此時bar函數(shù)中的this指向為全局執(zhí)行上下文中的this,即:window。


            再來看一個例子:


            var obj={

               foo: function() {

                   console.log(this); // obj

                   var bar=() => {

                       console.log(this); // obj

                   }

                   bar();

               }

            }

            obj.foo();

            在普通函數(shù)中,bar 執(zhí)行時內(nèi)部this被綁定為全局對象,因為它是作為獨立函數(shù)調(diào)用。但是在箭頭函數(shù)中呢,它卻綁定為 obj 。跟父級函數(shù)中的 this 綁定為同一對象。


            此時它的作用域鏈為:


            scopeChain = [

                bar.AO,

                obj.foo.AO,

                global.VO

            ]

            這個時候我們就差不多知道了箭頭函數(shù)中的this綁定。


            繼續(xù)看例子:


            var obj={

               foo: () => {

                   console.log(this); // window

                   var bar=() => {

                       console.log(this); // window

                   }

                   bar();

               }

            }

            obj.foo();

            這個時候怎么又指向了window了呢?


            我們還看當 bar 執(zhí)行時的作用域鏈:


            scopeChain = [

                bar.AO,

                obj.foo.AO,

                global.VO

            ]

            當我們找bar函數(shù)中的this綁定時,就會去找foo函數(shù)中的this綁定。因為它是繼承于它的。這時 foo 函數(shù)也是箭頭函數(shù),此時foo中的this綁定為window而不是調(diào)用它的obj對象。因此 bar函數(shù)中的this綁定也為全局對象window。


            我們在回頭看上面關于定時器中的this的例子:


            var name="chen";

            var obj={

               name: "erdong",

               foo: function() {

                   console.log(this.name); // erdong

                   setTimeout(function() {

                       console.log(this); // chen

                   },1000)

               }

            }

            obj.foo();

            這時我們就可以很簡單的讓定時器中的this與foo中的this綁定為同一對象:


            var name="chen";

            var obj={

               name: "erdong",

               foo: function() {

                   // this => obj

                   console.log(this.name); // erdong

                   setTimeout(() =>  {

                       // this => foo中的this => obj

                       console.log(this.name); // erdong

                   },1000)

               }

            }

            obj.foo();

            日歷

            鏈接

            個人資料

            藍藍設計的小編 http://www.dzxscac.cn

            存檔

            主站蜘蛛池模板: 日韩视频在线免费| 97久久超碰成人精品网站| 国产卡一卡二卡三无线乱码新区| 国产小屁孩cao大人免费| 呦女精品| 欧美人与禽猛交狂配| 国产高清成人免费视频在线观看| 网站免费视频www| 99久久精品费精品国产| 麻豆果冻国产剧情av在线播放| 少妇又色又爽又黄的视频| 国产福利姬喷水福利在线观看| 国产在线成人一区二区三区| 亚洲女优在线观看| 国产免费播放一区二区三区| 亚洲中文字幕无码永久在线不卡| 黄色av大全| 亚洲精品国产中文字幕| 亚洲国产良家在线观看| 黄色精品视频| 美女国产在线| 国产精品毛片大码女人| 琪琪午夜福利免费院| a天堂中文在线| 亚洲色图偷| 国模少妇一区二区三区| 蜜臀av久久国产午夜福利软件| 德国经典free性复古xxxx| 在线精品视频一区二区三区| 国产作爱视频免费播放| 在线观看视频国产| 亚洲精品国产精| 国产精品交换| 免费看又黄又爽又猛的视频软件| 中文精品在线| 久精品在线观看| 欧美亚洲色综久久精品国产| 日本在线观看| 久久性爱视频网站| 亚洲欧美日本韩国| 亚洲成在人线在线播放无码vr |