2.2 .this的綁定規則

来源:https://www.cnblogs.com/Tiancheng-Duan/archive/2018/01/16/8296908.html
-Advertisement-
Play Games

2.this的綁定規則 1.預設綁定 在代碼中,foo()函數不帶任何修飾的引用進行調用的,那麼只能使用預設綁定。 2.隱式綁定 調用位置使用obj上下文來引用函數foo2,故可以說函數被調用時obj對象“擁有”或“包含”該函數foo2()。那麼foo2函數被調用時,確實加上了對obj的引用。當函數 ...


2.this的綁定規則

1.預設綁定

1 function foo(  )
2 {
3    console.log(this.a);
4 }
5 var a=1;
6 foo();  //1

在代碼中,foo()函數不帶任何修飾的引用進行調用的,那麼只能使用預設綁定。


2.隱式綁定

1 function foo1()
2 {
3    console.log( this.a );
4 }
5 var obj = {
6    a: 1,
7    foo: foo1
8 };
9 obj.foo();  //1


調用位置使用obj上下文來引用函數foo2,故可以說函數被調用時obj對象“擁有”或“包含”該函數foo2()。
那麼foo2函數被調用時,確實加上了對obj的引用。當函數引用有上下文對象時,
隱式綁定規則會把函數調用中的this綁定到這個上下文對象。
故上文中的this.a等同於obj.a。


PS1:對象屬性引用鏈中只有上一層或者最後一層在調用位置中起作用。

 1 function foo2()
 2 {
 3    console.log( this.a );
 4 }
 5 var obj2 = {
 6    a: 2,
 7    foo: foo2
 8 };
 9 var obj1 = {
10    a: 3,
11    obj2: obj2
12 };
13 obj1.obj2.foo();    //2


距離this最近的對象上下文時obj2,故this.a等同與obj2.a,同時等同於obj1.obj2.a。


PS2:隱式丟失

 1 function foo3()
 2 {
 3    console.log( this.a );
 4 }
 5 var obj3 = {
 6    a: 33,
 7    foo: foo3
 8 };
 9 var bar=obj3.foo;
10 var a=3;
11 bar();  //3


這裡的要點就是關註var bar=obj3.foo;
雖然bar只是obj3.foo的一個引用,但bar實際引用的時foo3()函數本身。
因此此時的bar()其實是一個不帶任何修飾的函數調用,所以應用預設綁定。


PS2:隱式丟失(發生在函數調用時)。

 1 function foo4(  )
 2 {
 3    console.log(this.b);
 4 }
 5 function doFOO( fn )
 6 {
 7    var b=44;
 8    fn();
 9 }
10 var obj4={
11    b:10,
12    foo:foo4
13 };
14 var b=4;
15 doFOO(obj4.foo);    //4


參數傳遞其實就是一個隱式賦值,故傳入函數也會被隱式賦值。
所以結果與上面例子一致。
同理,這裡傳入的是自定義函數。即使傳入的是內置函數,結果也是一樣的。


PS3:如上所見,回調函數丟失this綁定是很常見的。
與此同時,另一種丟失情況更加出人意料:調用回調函數可能會修改this。
在一些流行的js庫中,事件處理器經常會把回調函數的this綁定到DOM元素上。



3.顯式綁定
顯式綁定,即是通過call,apply等方法來強制綁定。
call與apply的第一個參數都是thisObj,表示this的指向。第二個參數,call是輸入單個參數,apply是輸入參數數組。多個參數時,後者性能更優。

1 function foo()
2 {
3    console.log( this.a );
4 }
5 var obj = {
6    a: 3
7 };
8 foo.call( obj );   //2     函數沒有參數輸入時,call只需要一個參數thisObj輸入。


通過foo.call(),可以在調用foo時強制把它的this綁定到obj上。

PS1:“裝箱”
如果thisObj參數傳入的是一個原始值(簡單數據類型),這個原始值會被轉換成它的對象形式(如new String(..),new Boolean(..),或者new Number(..))。這通常稱為“裝箱”。

PS2:解決之前提出的丟失綁定問題。
1.硬綁定(顯式綁定的一個變種)

 1 function foo2()
 2 {
 3    console.log( this.a );
 4 }
 5 var obj2 = {
 6    a: 3
 7 };
 8 var bar = function()
 9 {
10    foo2.call( obj );
11 };
12 bar();  //3
13 setTimeout( bar, 100 ); //3
14 
15 //切記,硬綁定的bar不可能在修改它的this。
16 bar.call( window );   //3


硬綁定的典型應用場景就是創建一個包裹函數,負責接收參數並返回值;
另一個使用方法就是創建一個可以重覆應用的輔助函數:

 1 function foo3( something )
 2 {
 3    console.log( this.d, something );
 4    return this.d + something;
 5 }
 6 function bind( fn, obj )
 7 {
 8    return function()
 9    {
10       return fn.apply( obj, arguments );
11    };
12 }
13 var obj3 = {
14    d: 2
15 };
16 var bar3 = bind( foo3, obj3 );
17 var e = bar3( 3 );  //2 3
18 console.log( e ); //5


由於硬綁定是一個非常常用的模式,故ES5提供了一個內置方法bind,和上述用法類似。

 1 function foo4( something )
 2 {
 3    console.log( this.a4, something );
 4    return this.a4 + something;
 5 }
 6 var obj4 = {
 7    a4: 2
 8 };
 9 var bar4 = foo4.bind( obj4 );
10 var b4 = bar4( 5 ); //2 5
11 console.log( b4 );    //7


bind(..)會返回一個硬編碼的新函數(切記,新函數),這會將指定的參數設置為this的上下文並調用原始函數。

2.API調用的“上下文”
第三方庫的許多函數,以及JS語言和宿主環境(如瀏覽器環境)中許多內置函數,都提供了一個可選參數,通常稱為“上下文(context)。
其作用與bind(..)類似,確保回調函數使用指定的this。

 1 function foo5( el )
 2 {
 3    console.log( el, this.id );
 4 }
 5 var obj5 = {
 6    id: "awesome"
 7 };
 8 
 9 //調用foo5(..)函數是將this綁定到obj。
10 [ "1", 2, 3 ].forEach( foo5, obj5 );    //console.log輸出數字和字元串時,數字在前,字元串會有雙引號;反之則沒有。
11 // 1 awesome; 2 awesome; 3 awesome

 

4.new綁定
在此先糾正js中new與其他語言中new的區別。
在其它面向類語言中,”構造函數“是類中的一些特殊方法,使用new 初始化類時調用類中的構造函數。
在JS中,構造函數只是一些使用new操作符時被調用的函數。它們不屬於某個類,也不會實例化一個類。

JS中使用new來調用函數,或者說發生構造函數調用時,會自動執行以下操作。
  1.創建(或者說構造)一個全新的對象。
  2.這個新對象會被執行[[Prototype]]鏈接。
  3.這個新對象會綁定到函數調用的this。
  4.如果函數沒有返回其他對象,那麼new表達式中的函數調用會自動返回這個新對象。

1 function foo( a )
2 {
3    this.a = a;
4 }
5 var bar = new foo( 4 );
6 console.log( bar.a );
7 
8 //使用new來調用foo(..)時,會構建一個新對象並將它綁定到foo(..)調用的this上,並將該對象返回給bar。

 







您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 21、數組 定義數組 * 字面量方式 var 數組名稱 = [ value,value,... ] * 構造函數方式 var 數組名稱 = new Array(value,value,...); var 數組名稱 = new Array(length) 創建對象方式創建數組分析圖 附:var num ...
  • 閱讀本書主要目的: 自從學會CSS以來,雖然熟練掌握了其使用方法和技巧,但對其底層的原理和實現並不清晰,閱讀本書想進一步系統化的學習和深入研究其本質,對這門前端基礎語言從熟練使用到真正理解。 第1章 CSS和文檔 1.1 WEB的衰落(為了表現增加很多標記元素如font等,這些阻礙了頁面的結構化) ...
  • 眾所周知,文本溢出顯示省略號用CSS就可以: 單行文本: 多行文本: 如果想中間顯示省略號呢?? 現在需求是,一段文本很長,但最後有一個關鍵詞很重要,而且改關鍵詞有括弧括起來的,需要顯示出來,所以如果文本過長,不單隻做省略號處理,還要把括弧裡面的內容顯示出來。 上面的代碼意思是:如果文本長度大於13 ...
  • 三種密碼強度的正則表達式: 較弱:全是數字或全是字母 6-16個字元:/^[0-9]{6,16}$|^[a-zA-Z]{6,16}$/; 中級:數字、26個英文字母 6-16個字元: /^[A-Za-z0-9]{6,16}$/; 較高:由數字、26個英文字母或者下劃線組成的字元串 6-16個字元: ...
  • 1、概述 簡單值(基本類型)通過值複製的方式來賦值/傳遞。 複合值(對象)通過引用複製的方式來賦值/傳遞。 結合記憶體示意圖,理解會更深刻。 簡單類型的值在常量池只有一份,變數a和變數b都是常量池中2的一個副本。 變數c和變數d都是指向堆中的一個數組對象。 ...
  • <! TOC "作用域與閉包" "什麼是作用域" "編譯器" "理解作用域" "嵌套的作用域" "詞法作用域" "詞法分析時" "欺騙詞法作用域" "函數與塊作用域" "函數中的作用域" "隱藏標識符於普通作用域" "函數作為作用域" "塊作為作用域" "提升" "先有雞還是先有蛋?" "編譯器再次 ...
  • 本文詳細介紹了table-layout的屬性值、定義和用法、固定表格佈局、自動表格佈局等……希望可以幫到你喲! ...
  • 需求:用的heightcharts插件,點擊曲線圖想獲得所點擊點的返回值,如圖 問題代碼: (function chart_line(){ var data={"title":["01","02","03","04","05","06","07","08","09","10","11","12"], ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...