首先要說明的是本文中的this,與mvvm框架如vue,yox等的this是不一樣的,本文討論的this不包括外掛程式中對this變數的封裝使用。
一、this繫結
this的繫結想必是沒有什麼疑問的,取決於函式的呼叫位置。es6箭頭函式的this則取決於函式定義的位置。
所以想確定this變數究竟指向誰,就要先看函式執行過程中的呼叫位置或箭頭函式的定義位置。不過,記筆記當然不是記那些爛熟於心的東西,是要記那些之前被忽略的知識點。
1、嚴格模式與非嚴格模式下對this變數繫結的影響:
functionfoo()
var a = 2;
foo(); // typeerr: this is undefined
嚴格模式下,全域性物件不能用於預設繫結,所以這裡this指向的是undefined。然後我們看下面這段**:
functionfoo()
var a = 2;
(function
())();
由兩段**的對比可見:在嚴格模式下呼叫函式,並不會影響預設繫結。當然這種把嚴格模式跟非嚴格模式混著使用在開發中也是不會出現的。
2、**函式與settimeout等內建函式中
依然是先看乙個例子:
functionfoo()
var obj =
obj.foo(); //2
這個屬於乙個隱式繫結的例子,函式呼叫中的this會被繫結到呼叫的上下文物件上,既obj。故 this.a 相當於是 obj.a;
但是如果我們把obj.foo當做引數傳入settimeout中呢?
functionfoo()
var obj =
var a = 3;
settimeout(obj.foo, 1000); //
3
這是因為obj.foo其實是對foo函式的乙個引用,在settimeout中,相當於是:
functionsettimeout(fn, delay)
這樣看的話,foo函式在呼叫時並沒有上下文,故它使用了預設繫結,繫結到了全域性物件上。**函式的原理也是類似的。這種現象稱之為隱式丟失。
隱式丟失:被隱式繫結的函式丟失了繫結物件,使用預設繫結,從而把this繫結到全域性物件或者undefined上。
我們用**來理解什麼是硬繫結:
functionfoo()
var obj =
function
bar()
var a = 3;
settimeout(bar,200); //2
上面的例子,不管bar在**呼叫,裡面的foo函式的指向都是obj;永遠都是obj來呼叫foo函式。這種強制繫結稱之為硬繫結。
上面的強制繫結,可以用bind來簡化下:
functionfoo()
var obj =
var bar =foo.bind(obj);
var a = 3;
settimeout(bar,200);
bind(..)會返回乙個硬編碼的新函式,它會把你指定的引數設定為this的上下文並呼叫原始函式。
還有乙個常見的對this繫結有影響的寫法:使用 new 關鍵字來呼叫函式:
functionfoo(a)
var a = 2;
var bar = new foo(3);
console.log(bar.a); //3
這裡有乙個點要強調,在js中,使用new關鍵字來新建乙個物件,跟物件導向語言中使用new初始化類是不一樣的。j物件導向語言中使用new初始化類,是呼叫類中的建構函式。
js中並沒有所謂的建構函式,只有對函式的「構造呼叫」;
比如上段**中,通過 new 關鍵字建立的bar,console以後的結果,是個普通的物件:;通過new關鍵字建立bar,會自動執行以下操作:
1、建立(構造)乙個全新的物件;
2、這個新物件會被執行 prototype 連線;
3、這個新物件會繫結到函式呼叫的this;
4、如果函式沒有返回其他物件,那麼new表示式中的函式呼叫會自動返回這個新物件。
接下來我們思考乙個問題,如果我先使用強繫結,後使用new關鍵字,那this究竟會被繫結到哪乙個物件上?
functionfoo(num)
var obj ={};
var bar =foo.bind(obj);
bar(2);
console.log(obj.a);//2
var baz = new bar(3);
console.log(obj.a); //2
console.log(baz.a); //
3
我們看出,通過 new 關鍵字 新建的物件baz,baz.a的結果,與obj.a的結果並不相等,說明new修改了foo對於obj的強繫結,new關鍵字的優先順序要高於強繫結。
1、函式是否在 new 中呼叫 ? 如果是,this繫結的是新建立的物件。
3、函式是否在某個上下文物件中呼叫(隱式繫結)?如果是的話,this繫結的是那個上下文物件;
4、如果都不是,使用預設繫結,如果在嚴格模式下,就繫結到undefined,否則繫結到全域性物件。
function
foo(a,b)
var obj = object.create(null
);這裡插一句題外話:如果哪位大神知道yox.js框架做國際化的方案,煩請指教一二。ps: 不考慮構建工具的國際化方案;
js外掛程式概念
1 理論 module 模組,模組化開發。把業務需求分模組。每乙個模組負責乙個功能的實現。2 概念 匿名函式 宣告並執行 function 有名字的函式 宣告並執行 var func function func 3 外掛程式寫法 3.1 物件導向思想類方式 new 物件名.方法 自定義類 funct...
筆記 JS高階程式設計 基本概念篇
1 js中的一切 變數,函式名和操作符 都是區分大小寫的 2 識別符號 變數,函式,屬性的名字,以及函式的引數 第乙個字元必須是字母,下劃線,或者美元 書寫方式採用駝峰式,不能將關鍵字作為識別符號。3 js的變數是鬆散型別,每個變數僅僅是乙個用於儲存值的佔位符,未初始化的變數都會儲存乙個特殊值 un...
js課程 1 2 js概念
getelement獲取的是標籤,是元素,同樣也是js物件,也有屬性和方法,方法就是onclick這些事件,屬性就是固有的屬性 13 找到小狗 14 dogobj document.getelementbyid dogid 15 16 給小狗加事件 17 dogobj.nclick function...