成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

關(guān)于this的全面解析(上)

caige / 2767人閱讀

摘要:關(guān)于的全面解析下頁(yè)面鏈接的調(diào)用位置調(diào)用位置就是函數(shù)在代碼中被調(diào)用的位置而不是聲明的位置,尋找調(diào)用位置就是尋找函數(shù)被調(diào)用的位置,最重要的是分析調(diào)用棧就是為了到達(dá)當(dāng)前執(zhí)行位置所調(diào)用的所有函數(shù)。因此,調(diào)用函數(shù)時(shí)被綁定到這個(gè)對(duì)象上,所以和是一樣的。

關(guān)于this的全面解析(下)頁(yè)面鏈接

this的調(diào)用位置

調(diào)用位置就是函數(shù)在代碼中被調(diào)用的位置(而不是聲明的位置),尋找調(diào)用位置就是尋找“函數(shù)被調(diào)用的位置”,最重要的是分析調(diào)用棧(就是為了到達(dá)當(dāng)前執(zhí)行位置所調(diào)用的所有函數(shù))。

   function baz() {
        //當(dāng)前調(diào)用棧是baz
        //當(dāng)前調(diào)用位置是全局位置
        console.log("baz");
        bar(); //<--bar的調(diào)用位置
    }

    function bar() {
        //當(dāng)前的調(diào)用棧是baz->bar
        //因此當(dāng)前的調(diào)用位置在baz中
        console.log("bar");
        foo(); //<--foo的調(diào)用位置
    }

    function foo() {
        //當(dāng)前的調(diào)用棧是baz->bar->foo
        //因此當(dāng)前的調(diào)用位置在bar中
        console.log("foo");
    }
    baz(); //<-baz的調(diào)用位置

把調(diào)用棧想象成一個(gè)函數(shù)調(diào)用鏈,如上圖代碼中的樣式,但是這種方法非常麻煩并且容易出錯(cuò)。另一個(gè)查看調(diào)用棧的方法是使用瀏覽器的調(diào)試工具。

綁定規(guī)則

首先需要找到調(diào)用位置,然后判斷尋求下列四條規(guī)則中的哪一條。

1 默認(rèn)綁定

首先介紹最常用的函數(shù)調(diào)用類型:獨(dú)立函數(shù)調(diào)用。可以把這條規(guī)則看作是無(wú)法應(yīng)用其他規(guī)則時(shí)的默認(rèn)規(guī)則。

function foo() {
        console.log(this.a); //<-this指向全局作用域
    }
    var a = 2;
    foo(); //<-foo調(diào)用位置

在代碼中,foo()是直接使用不帶任何修飾的函數(shù)引用進(jìn)行調(diào)用的,因此只能使用默認(rèn)綁定,無(wú)法應(yīng)用其他規(guī)則。

function foz() {
        "use strict";
        console.log(this.a); //<--嚴(yán)格模式下不能將全局對(duì)象用于綁定

    }
    foz(); //TypeError

2 隱藏綁定

另一條需要考慮的規(guī)則是調(diào)用位置是否有上下文對(duì)象,或者說是否被某個(gè)對(duì)象擁有或者包含,這種說法有時(shí)候會(huì)有誤導(dǎo)。

function foa() {
        console.log(this.a);
    }
    var foaObj = {
        a: "Hello",
        foa: foa //<--foa函數(shù)調(diào)用位置
    }
    foaObj.foa();

foa函數(shù)在嚴(yán)格意義上來說不屬于foaObj對(duì)象。然而,調(diào)用位置會(huì)使用foaObj上下文來引用函數(shù),因此可以判斷為函數(shù)調(diào)用時(shí),foaObj對(duì)象包含并引用它。

當(dāng)函數(shù)引用有上下文對(duì)象時(shí),隱式綁定規(guī)則會(huì)把函數(shù)調(diào)用中的this綁定到這個(gè)上下文對(duì)象。因此,調(diào)用foa函數(shù)時(shí)this被綁定到foaObj這個(gè)對(duì)象上,所以this.a 和 foaObj.a 是一樣的。

然而,有一個(gè)常見的this綁定問題就是被隱式綁定的函數(shù)會(huì)丟失綁定對(duì)象,也就是說它會(huì)應(yīng)用默認(rèn)綁定,從而把this綁定到全局對(duì)象或undefined上。

function fob() {
        console.log(this.a);
    }
    var fobObj = {
        a: "Hello",
        fob: fob
    }
    var focObj = fobObj.fob;
    var a = 1; //a是全局對(duì)象的屬性
    focObj();

focObj引用實(shí)際上是fob函數(shù),所以this綁定的是全局對(duì)象中的a。

3 顯式綁定

就像我們剛才看到的那樣,在分析隱式綁定時(shí),我們必須在一個(gè)對(duì)象內(nèi)部包含一個(gè)指向函數(shù)的屬性,并通過這個(gè)屬性間接引用函數(shù),從而把this間接綁定到這個(gè)對(duì)象上。

JavaScript提供的絕大多數(shù)函數(shù)以及你自己創(chuàng)建的所有函數(shù)都可以使用call(…) 和 apply (…) 方法。

這兩個(gè)方法的第一參數(shù)是一個(gè)對(duì)象,是給this準(zhǔn)備的,接著在調(diào)用函數(shù)時(shí)將其綁定到this。因?yàn)槟憧梢灾苯又付╰his的綁定對(duì)象,因此我們稱之為顯式綁定。

function fod() {
        console.log(this.a);
    }
    var fodObj = {
        a: 2
    }
    fod.call(fodObj); //2

通過fod.call(…)方法,可以強(qiáng)制把this綁定到fodObj這個(gè)對(duì)象上。

然而,顯示綁定仍然無(wú)法解決之前提出的丟失綁定問題。

但是顯示綁定的一個(gè)變種可以解決這個(gè)問題。

 function foh() {
        console.log(this.a);
    }
    var fohObj = {
        a: 2
    }
    var baa = function() {
        foh.call(fohObj);
    }
    baa(); //2
    setTimeout(baa, 100); //2
    baa.call(window); //2

我們創(chuàng)建了一個(gè)baa函數(shù),并在它的內(nèi)部手動(dòng)調(diào)用了foh.call(fohObj),因此強(qiáng)制把foh的this綁定到了fohObj上。無(wú)論之后如何調(diào)用函數(shù)baa,它總會(huì)手動(dòng)在fohObj上調(diào)用foh。這種綁定是一種顯示的強(qiáng)制綁定,因此我們稱之為硬綁定。

硬綁定的典型應(yīng)用場(chǎng)景就是創(chuàng)建一個(gè)包裹函數(shù),負(fù)責(zé)接收參數(shù)并返回值。

function foi(something) {
        console.log(this.a, something);
        return this.a + something;
    }
    var foiObj = {
        a: 2
    }
    var bae = function() {
        return foi.apply(foiObj, arguments);
    }
    var b = bae(3);
    console.log(b);

另一種使用方法是創(chuàng)建一個(gè)可以重復(fù)使用的輔助函數(shù)。

function fol(something) {
        console.log(this.a, something);
        return this.a + something;
    }

    function bind(fn, obj) {
        return function() {
            return fn.apply(obj, arguments);
        }
    }
    var folObj = {
        a: 3
    }
    var bac = bind(fol, folObj);
    var c = bac(4);
    console.log(c);

4 new綁定

使用new來調(diào)用函數(shù),或者說發(fā)生構(gòu)造函數(shù)調(diào)用時(shí),會(huì)自動(dòng)執(zhí)行下面的操作。

1) 創(chuàng)建(或者說構(gòu)造)一個(gè)全新的對(duì)象。
2) 這個(gè)新對(duì)象會(huì)被執(zhí)行Prototype連接。
3) 這個(gè)新對(duì)象會(huì)綁定到函數(shù)調(diào)用的this。
4) 如果函數(shù)沒有返回其他對(duì)象,那么new表達(dá)式中的函數(shù)調(diào)用會(huì)自動(dòng)返回這個(gè)新對(duì)象。

function abc(a) {
        this.a = a;
    }
    var x = new abc(10);
    console.log(x.a);

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/79663.html

相關(guān)文章

  • 關(guān)于this全面解析(下)

    摘要:關(guān)于的全棉解析上的文章地址判斷函數(shù)是否在中調(diào)用綁定如果是的話綁定的是新創(chuàng)建的對(duì)象。顯而易見,這種方式可能會(huì)導(dǎo)致許多難以分析和追蹤的。默認(rèn)在嚴(yán)格模式下綁定到,否則綁定到全局對(duì)象。 關(guān)于this的全棉解析(上)的文章地址 判斷this 函數(shù)是否在new中調(diào)用(new綁定)?如果是的話this綁定的是新創(chuàng)建的對(duì)象。 bar = new foo() 函數(shù)是否通過call、apply(顯式綁定...

    philadelphia 評(píng)論0 收藏0
  • this全面解析(一)

    摘要:調(diào)用棧就是為了到達(dá)當(dāng)前執(zhí)行位置所調(diào)用的所有函數(shù)。由于無(wú)法控制回調(diào)函數(shù)的執(zhí)行方式,因此就沒有辦法控制調(diào)用位置得到期望的綁定,下一節(jié)我們會(huì)介紹如何通過固定來修復(fù)這個(gè)問題。 在《你不知道的this》中我們排除了對(duì)于this的錯(cuò)誤理解,并且明白了每個(gè)函數(shù)的this是在調(diào)用時(shí)綁定的,完全取決于函數(shù)的調(diào)用位置。在本節(jié)中我們主要介紹一下幾個(gè)主要內(nèi)容: 什么是調(diào)用位置 綁定規(guī)則 this詞法 調(diào)用...

    darry 評(píng)論0 收藏0
  • this全面解析(二)

    摘要:在傳統(tǒng)的面向類的語(yǔ)言中,構(gòu)造函數(shù)是類中的一些特殊方法,使用初始化類是會(huì)調(diào)用類中的構(gòu)造函數(shù)。 在上一節(jié)中我們?cè)敿?xì)介紹了this的兩種綁定方式,默認(rèn)綁定和隱式綁定,在這一節(jié)我們繼續(xù)介紹this的另外兩種綁定方式顯示綁定和new綁定。那么,我們要解決的問題當(dāng)然就是上一節(jié)中我們提到的:this丟失! 顯式綁定 在隱式綁定中,我們必須在一個(gè)對(duì)象的內(nèi)部包含一個(gè)指向函數(shù)的屬性,并通過這個(gè)屬性間接引用...

    iflove 評(píng)論0 收藏0
  • Java雜記17—String全面解析

    摘要:所以也就是說在沒有的基礎(chǔ)上,執(zhí)行代碼會(huì)在串池中創(chuàng)建一個(gè),也會(huì)在堆內(nèi)存中再出來一個(gè)。不可變性的優(yōu)點(diǎn)安全性字符串不可變安全性的考慮處于兩個(gè)方面,數(shù)據(jù)安全和線程安全。 摘要: String基本特性,String源碼,為什么String不可變? 前言 基于字符串String在java中的地位,關(guān)于String的常識(shí)性知識(shí)就不多做介紹了,我們先來看一段代碼 public class Test {...

    jeffrey_up 評(píng)論0 收藏0
  • 剖析非同質(zhì)化代幣ERC721-全面解析ERC721標(biāo)準(zhǔn)

    摘要:本文就來剖析下什么是是什么在創(chuàng)建代幣一篇,我們講到過代幣,和一樣,同樣是一個(gè)代幣標(biāo)準(zhǔn),官方簡(jiǎn)要解釋是,簡(jiǎn)寫為,多翻譯為非同質(zhì)代幣。返回合約代幣符號(hào),盡管是可選,但強(qiáng)烈建議實(shí)現(xiàn),即便是返回空字符串。 本文首發(fā)于深入淺出區(qū)塊鏈社區(qū)原文鏈接:剖析非同質(zhì)化代幣ERC721-全面解析ERC721標(biāo)準(zhǔn)原文已更新,請(qǐng)讀者前往原文閱讀 什么是ERC-721?現(xiàn)在我們看到的各種加密貓貓狗狗都是基于ERC...

    Sike 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<