久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      什么是this?深入解析JavaScript中的this

      什么是this?下面本篇文章給大家介紹一下JavaScript中的this,并聊聊this在函數(shù)不同調(diào)用方式下的區(qū)別,希望對大家有所幫助!

      什么是this?深入解析JavaScript中的this

      JavaScript中的this格外的不一樣,比如Java語言中的this是在代碼的執(zhí)行階段是不可更改,而JavaScript的this是在調(diào)用階段進(jìn)行綁定。因?yàn)檫@一性質(zhì)所以給了this很大的發(fā)揮空間。但其在嚴(yán)格模式和非嚴(yán)格模式下又有些不一樣,在函數(shù)的不同調(diào)用方式也導(dǎo)致this有些區(qū)別。

      什么是this?

      首先對this的下個(gè)定義:this是在執(zhí)行上下文創(chuàng)建時(shí)確定的一個(gè)在執(zhí)行過程中不可更改的變量。

      所謂執(zhí)行上下文,就是JavaScript引擎在執(zhí)行一段代碼之前將代碼內(nèi)部會(huì)用到的一些變量、函數(shù)、this提前聲明然后保存在變量對象中的過程。這個(gè)'代碼片段'包括:全局代碼(script標(biāo)簽內(nèi)部的代碼)、函數(shù)內(nèi)部代碼、eval內(nèi)部代碼。而我們所熟知的作用域鏈也會(huì)在保存在這里,以一個(gè)類數(shù)組的形式存儲(chǔ)在對應(yīng)函數(shù)的[[Scopes]]屬性中。

      this只在函數(shù)調(diào)用階段確定,也就是執(zhí)行上下文創(chuàng)建的階段進(jìn)行賦值,保存在變量對象中。這個(gè)特性也導(dǎo)致了this的多變性:即當(dāng)函數(shù)在不同的調(diào)用方式下都可能會(huì)導(dǎo)致this的值不同。

      上面我們說過了在嚴(yán)格模式下和非嚴(yán)格模式下this表現(xiàn)不同:

      var a = 1; function fun() {    'use strict';     var a = 2;       return this.a; } fun();//報(bào)錯(cuò) Cannot read property 'a' of undefined
      • 嚴(yán)格模式下,this指向undefined;

      var a = 1; function fun() {     var a = 2;       return this.a; } fun();//1
      • 非嚴(yán)格模式下this指向window;

      上面同一段代碼,在不同模式下之所以有不同表現(xiàn),就是因?yàn)閠his在嚴(yán)格模式,非嚴(yán)格模式下的不同。

      結(jié)論:當(dāng)函數(shù)獨(dú)立調(diào)用的時(shí)候,在嚴(yán)格模式下它的this指向undefined,在非嚴(yán)格模式下,當(dāng)this指向undefined的時(shí)候,自動(dòng)指向全局對象(瀏覽器中就是window)

      多提一句,在全局環(huán)境下,this就是指向自己,再看一個(gè)例子:

      this.a = 1; var b = 1; c = 1; console.log(this === window)//true //這三種都能得到想要的結(jié)果,全局上下文的變量對象中存在這三個(gè)變量

      再多提一句,當(dāng)this不在函數(shù)中用的時(shí)候會(huì)怎樣?看一個(gè)例子:

      var a = 1000; var obj = {     a: 1,       b: this.a + 1 } function fun() {     var obj = {           a: 1,         c: this.a + 2 //嚴(yán)格模式下這塊報(bào)錯(cuò) Cannot read property 'a' of undefined     }     return obj.c; } console.log(fun());//1002 console.log(obj.b);//1001

      這種情況下this還是指向了window。那么我們可以單獨(dú)下個(gè)結(jié)論:

      當(dāng)obj在全局聲明的時(shí)候,obj內(nèi)部屬性中的this指向全局對象,當(dāng)obj在一個(gè)函數(shù)中聲明的時(shí)候,嚴(yán)格模式下this會(huì)指向undefined,非嚴(yán)格模式自動(dòng)轉(zhuǎn)為指向全局對象。

      好了,剛剛小試牛刀下,知道了嚴(yán)格模式和非嚴(yán)格模式下this的區(qū)別,然而我們?nèi)粘?yīng)用最多的還是在函數(shù)中用this,上面也說過了this在函數(shù)的不同調(diào)用方式還有區(qū)別,那么函數(shù)的調(diào)用方式都有哪些呢?四種:

      • 在全局環(huán)境或是普通函數(shù)中直接調(diào)用
      • 作為對象的方法
      • 使用apply和call
      • 作為構(gòu)造函數(shù)

      下面分別就四種情況展開:

      直接調(diào)用

      上面的例子,其實(shí)就是直接調(diào)用的,不過我決定再寫一個(gè)例子:

      var a = 1; var obj  =  {     a: 2,       b: function () {         function fun() {           return this.a         }        console.log(fun());     } }  obj.b();//1

      fun函數(shù)雖然在obj.b方法中定義,但它還是一個(gè)普通函數(shù),直接調(diào)用在非嚴(yán)格模式下指向undefined,又自動(dòng)指向了全局對象,正如預(yù)料,嚴(yán)格模式會(huì)報(bào)錯(cuò)undefined.a不成立,a未定義。

      重要的事情再說一遍:當(dāng)函數(shù)獨(dú)立調(diào)用的時(shí)候,在嚴(yán)格模式下它的this指向undefined,在非嚴(yán)格模式下,當(dāng)this指向undefined的時(shí)候,自動(dòng)指向全局對象(瀏覽器中就是window)。

      作為對象的方法

      var a = 1; var obj = {   a: 2,   b: function() {     return this.a;   } } console.log(obj.b())//2

      b所引用的匿名函數(shù)作為obj的一個(gè)方法調(diào)用,這時(shí)候this指向調(diào)用它的對象。這里也就是obj。那么如果b方法不作為對象方法調(diào)用呢?啥意思呢,就是這樣:

      var a = 1; var obj = {   a: 2,   b: function() {     return this.a;   } } var t = obj.b; console.log(t());//1

      如上,t函數(shù)執(zhí)行結(jié)果竟然是全局變量1,為啥呢?這就涉及Javascript的內(nèi)存空間了,就是說,obj對象的b屬性存儲(chǔ)的是對該匿名函數(shù)的一個(gè)引用,可以理解為一個(gè)指針。當(dāng)賦值給t的時(shí)候,并沒有單獨(dú)開辟內(nèi)存空間存儲(chǔ)新的函數(shù),而是讓t存儲(chǔ)了一個(gè)指針,該指針指向這個(gè)函數(shù)。相當(dāng)于執(zhí)行了這么一段偽代碼:

      var a = 1; function fun() {//此函數(shù)存儲(chǔ)在堆中     return this.a; } var obj = {   a: 2,   b: fun //b指向fun函數(shù) } var t = fun;//變量t指向fun函數(shù) console.log(t());//1

      此時(shí)的t就是一個(gè)指向fun函數(shù)的指針,調(diào)用t,相當(dāng)于直接調(diào)用fun,套用以上規(guī)則,打印出來1自然很好理解了。

      使用apply,call

      關(guān)于apply和call是干什么的怎么用本文不涉及,請移駕:apply,call

      這是個(gè)萬能公式,實(shí)際上上面直接調(diào)用的代碼,我們可以看成這樣的:

      function fun() {       return this.a; } fun();//1 //嚴(yán)格模式 fun.call(undefined) //非嚴(yán)格模式 fun.call(window)

      這時(shí)候我們就可以解釋下,為啥說在非嚴(yán)格模式下,當(dāng)函數(shù)this指向undefined的時(shí)候,會(huì)自動(dòng)指向全局對象,如上,在非嚴(yán)格模式下,當(dāng)調(diào)用fun.call(undefined)的時(shí)候打印出來的依舊是1,就是最好的證據(jù)。

      為啥說是萬能公式呢?再看函數(shù)作為對象的方法調(diào)用:

      var a = 1; var obj = {   a: 2,   b: function() {     return this.a;   } } obj.b() obj.b.call(obj)

      如上,是不是很強(qiáng)大,可以理解為其它兩種都是這個(gè)方法的語法糖罷了,那么apply和call是不是真的萬能的呢?并不是,ES6的箭頭函數(shù)就是特例,因?yàn)榧^函數(shù)的this不是在調(diào)用時(shí)候確定的,這也就是為啥說箭頭函數(shù)好用的原因之一,因?yàn)樗膖his固定不會(huì)變來變?nèi)サ牧?。關(guān)于箭頭函數(shù)的this我們稍后再說。

      作為構(gòu)造函數(shù)

      何為構(gòu)造函數(shù)?所謂構(gòu)造函數(shù)就是用來new對象的函數(shù),像Function、Object、Array、Date等都是全局定義的構(gòu)造函數(shù)。其實(shí)每一個(gè)函數(shù)都可以new對象,那些批量生產(chǎn)我們需要的對象的函數(shù)就叫它構(gòu)造函數(shù)罷了。注意,構(gòu)造函數(shù)首字母記得大寫。

      function Fun() {   this.name = 'Damonre';   this.age = 21;   this.sex = 'man';   this.run = function () {     return this.name + '正在跑步';   } } Fun.prototype = {   contructor: Fun,   say: function () {     return this.name + '正在說話';   } } var f = new Fun(); f.run();//Damonare正在跑步 f.say();//Damonare正在說話

      如上,如果函數(shù)作為構(gòu)造函數(shù)用,那么其中的this就代表它即將new出來的對象。為啥呢?new做了啥呢?

      偽代碼如下:

      function Fun() {   //new做的事情   var obj = {};   obj.__proto__ = Fun.prototype;//Base為構(gòu)造函數(shù)   obj.name = 'Damonare';   ...//一系列賦值以及

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號