中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript?this綁定與this指向問題如何解決

發布時間:2023-02-27 14:44:11 來源:億速云 閱讀:90 作者:iii 欄目:開發技術

本篇內容主要講解“JavaScript this綁定與this指向問題如何解決”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“JavaScript this綁定與this指向問題如何解決”吧!

    一、this 綁定

    怎么理解 this?

    其實 this 就是一個指針,它指示的就是當前的一個執行環境,可以用來對當前執行環境進行一些操作。

    MDN 解釋:在絕大多數情況下,函數的調用方式決定了 this 的值(運行時綁定)。this 不能在執行期間被賦值,并且在每次函數被調用時 this 的值也可能會不同。ES5 引入了 bind 方法來設置函數的 this 值,而不用考慮函數如何被調用的。ES2015 引入了箭頭函數,箭頭函數不提供自身的 this 綁定(this 的值將保持為閉合詞法上下文的值)。

    this 是如何綁定的?

    每個函數的 this 是在調用時被綁定的,完全取決于函數的調用位置。我們找到函數的調用位置,然后運用以下四種綁定規則來判斷函數的 this 指向。

    1、默認綁定

    函數的 this 會默認綁定到全局對象 window 上,如果在嚴格模式中,this 綁定到 undefined。

    function foo (){
      console.log(this.a)
    }
    let a = 1
    foo() // 1

    2、隱式綁定

    調用位置是否有上下文對象,或者被某個對象擁有或包含。

    function foo(){
      console.log(this.a)
    }
    let obj = {
      a: 2,
      foo:foo
    }
    let a = 1
    obj.foo(); // 2
    
    function foo(){
      console.log(this.a)
    }
    let obj1 = {
      a: 2,
      foo: foo
    }
    let obj2 = {
      a: 3,
      obj1: obj1
    }
    let a = 1
    obj2.obj1.foo(); // 2

    3、顯式綁定

    直接改變 this 指向,綁定到另一個執行環境

    function foo(){
      console.log(this.a)
    }
    let obj = {
      a: 1
    }
    foo.call(obj)

    4、new 綁定

    new 出來的函數 this 綁定的是新創建的對象

    function Foo(a){
      this.a = a
    }
    let bar = new Foo(2)
    console.log(bar.a) // 2

    this 綁定優先級

    默認綁定的優先級是最低的

    new 綁定 > 顯式綁定 > 隱式綁定 > 默認綁定

    1、顯示綁定 VS 隱式綁定

    function foo(){
      console.log(this.a)
    }
    let obj1 = {
      a: 1,
      foo: foo
    }
    let obj2 = {
      a: 2
    }
    console.log(obj1.foo()) // 1
    obj1.foo.call(obj2) // 2

    通過以上代碼我們可以看到 顯式綁定 的優先級高于 隱式綁定

    2、顯示綁定 VS new 綁定

    function foo(a){
      this.a = a
    }
    let obj1 = {
      foo
    }
    let bar = foo.bind(obj1)
    bar(2)
    console.log(obj1.a) // 2
    let bar2 = new bar(3)
    console.log(obj1.a) // 2
    console.log(bar2.a) // 3

    new 修改了顯示綁定 調用 bar 中的 this,所以 new 綁定的優先級高于顯式綁定

    二、this 指向

    判斷準則

    第一準則:this 永遠指向函數運行時所在的對象,而不是函數被創建時所在的對象。(不包含箭頭函數)

    第二準則:無論是否在嚴格模式下,在全局執行環境中(在任何函數體外部)this 都指向全局對象

    判斷順序

    • 函數是否在 new 中調用,如果是的話 this 綁定的是新創建的對象;

    • 函數是否通過 call、apply、bind 的方式調用,如果是的話 this 綁定的是指定的對象;

    • 函數是否在某個上下文中被調用,如果是的話 this 綁定的是函數調用的上下文;

    • 除此之外 this 綁定的就是全局對象 在嚴格模式下綁定的是 undefined。

    常見的指向問題

    • 箭頭函數沒有自己的 this 指針(需要從執行上下文來進行判斷)

    三、改變 this 指向

    有四種方式

    • 變量保存 this:將 this 臨時保存下來

    • call():使用一個指定的 this 值和單獨給出的一個或多個參數來調用一個函數。

    • bind():會有一個返回值,返回值是一個擁有第一個函數作用域的新的函數體

    • apply():調用一個具有給定 this 值的函數,以及以一個數組(或一個類數組對象)的形式提供的參數。

    變量保存 this

    var _this = window;
    var obj = {
        name:"張三",
        show:function(){
            console.log(this) //obj
            console.log(_this) // window
        }
    }
    obj.show()

    call

    call() 方法使用一個指定的 this 值和單獨給出的一個或多個參數來調用一個函數。

    函數名稱.bind(參數1,參數2,a,b,c.....)
        參數1:當前函數的作用域
        參數2:需要傳遞的參數,參數是一個一個傳

    function fn(a,b){
        console.log(this,a,b)
    }
    document.onclick = functioin(){
        fn.call(document,1,2)
    }

    可以使用 call 來實現繼承:寫一個方法,然后讓另外一個新的對象來繼承它(而不是在新對象中再寫一次這個方法)。

    function Product(name, price) {
      this.name = name;
      this.price = price;
    }
    function Food(name, price) {
      Product.call(this, name, price);
      this.category = 'food';
    }
    function Toy(name, price) {
      Product.call(this, name, price);
      this.category = 'toy';
    }
    var cheese = new Food('feta', 5);
    var fun = new Toy('robot', 40);

    bind

    bind 創建一個新的函數,在 bind() 被調用時,這個新函數的 this 被指定為 bind() 的第一個參數,而其余參數將作為新函數的參數,供調用時使用。

    特性就是會有一個返回值,返回值是一個擁有第一個函數作用域的新的函數體

    函數名稱.bind(參數1,參數2.....)() // 必須調用一下
        參數1:當前函數的作用域
        參數2:需要傳遞的參數

    var obj = {
        name:"張三",
        show:function(val){
            console.log(this) //obj  沒有修改前
            console.log(this,1) // document 1     修改后
        }
    }
    obj.show().bind(document,1)()

    MDN:ECMAScript 5 引入了 Function.prototype.bind()。調用 f.bind(someObject) 會創建一個與 f 具有相同函數體和作用域的函數,但是在這個新函數中,this 將永久地被綁定到了 bind 的第一個參數,無論這個函數是如何被調用的。

    apply

    apply() 方法調用一個具有給定 this 值的函數,以及以一個數組(或一個類數組對象)的形式提供的參數。

    函數名稱.bind(參數1,[參數2,a,b,c.....])
        參數1:當前函數的作用域
        參數2:需要傳遞的參數   數組

    function fn(a,b,c){
        console.log(this,a,b,c)
    }
    document.onclick = functioin(){
        fn.apply(document,[1,2,3])
    }

    call ,apply ,bind 三者的區別

    不同點:

    • bind 會有一個返回值,返回值是函數體,因此需要加上 () 才能調用 

    • call,apply 是沒有返回值的,當改變函數 this 指向的時候,函數就會執行,不需要加 () 調用

    • call 傳遞參數的時候是一個一個傳遞的

    • apply 是傳遞一個數組或者類數組對象的參數

    到此,相信大家對“JavaScript this綁定與this指向問題如何解決”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    孟州市| 习水县| 宝山区| 梅州市| 九龙坡区| 额尔古纳市| 丘北县| 怀远县| 丰顺县| 嘉峪关市| 苍山县| 毕节市| 荔波县| 浮山县| 化德县| 绩溪县| 淮安市| 阜南县| 清镇市| 抚州市| 淄博市| 盖州市| 涞源县| 乌苏市| 墨竹工卡县| 灌阳县| 龙井市| 米易县| 六安市| 吴忠市| 镇平县| 富阳市| 武威市| 高密市| 本溪| 上林县| 文安县| 正阳县| 浙江省| 蒙自县| 西贡区|