'JavaScript中的this'

"

1:基本概念

this字面意思是當前,當前執行代碼的環境對象或者是上下文。代表著當前方法執行的環境上下文,那麼何為環境上下文,通俗的說,誰調用了函數,誰就是這個函數的環境上下文。

在js中,this只有兩種指向,一種是指向當前的封閉作用域,或者是指向當前作用域的外層,this的最頂層就是window對象

關於this必須要了解的是嚴格模式,嚴格模式是js裡面的一個子集,是具有限制性JavaScript變體,嚴格模式也是js的一種,但是加了一些限制。

比如:

  • 在嚴格模式下通過拋出錯誤來消除了一些原有的靜默錯誤(靜默錯誤:語法有錯誤但是js並沒有提示,默認允許這個操作)。比如要取一個函數的傳入參數,在非嚴格模式下,可以直接拿到它的grument,但在嚴格模式下會拋出一個錯誤。
  • 嚴格模式修復了一些導致JavaScript引擎難以執行優化的缺陷
  • 禁用了在ECMAScript的未來版本中可能會定義的一些語法

進入"嚴格模式"的標誌:"use strict";

// 為整個腳本開啟嚴格模式 
"use strict";
var v = "Hi! I'm a strict mode script!";

// 為函數開啟嚴格模式
function strict() {
'use strict';
function nested() {
return "And so am I!";
}
return "Hi! I'm a strict mode function! " + nested();
}

2:全局環境

在全局環境下,無論是否在嚴格模式下,在全局執行環境下(任何函數體外部)this指向全局對象。也就是說在全局執行環境,這個this永遠指向全局對象,這個全局對象在瀏覽器中就是window。

//瀏覽器環境
var name = 'Eric';
console.log(window.name === this.name); /* true */
console.log(window === this); /* true */

3:函數體內部

在函數體內部,this的值取決於函數被調用的方式。函數被調用的方式有很多種:

簡單調用,也就是說沒有添加任何額外的操作,沒有添加一個this的綁定或者是改變。

簡單調用分為嚴格模式與非嚴格模式。

  • 在非嚴格模式下,this默認指向全局對象。
// 瀏覽器環境
function simple(){
return this;
}
console.log(simple() === window);
// true
  • 在嚴格模式下,保持進入執行環境時的值,沒有指定時默認undefined。
// 瀏覽器環境
function simple2(){
"use strict";
return this;
}
simple2() === undefined;
// true
window.simple2() === window;
// true

this傳遞,在js中this綁定有兩種:

  • 一種是call/apply,可以看作是一種,它們都是一個綁定this的立即執行的一個方法,綁定之後會立即執行這個函數,兩者的區別在於傳遞參數的不同,一個是傳一個參數,一個是傳一堆參數;call/apply實際上是綁定值的是一個對象,存在一個ToObject過程。call/apply是一個立即執行的綁定this的一個操作。
// 瀏覽器環境 
var object = {
name: 'Eric'
};
var name = 'Iven';
function getName(arg) {
return this.name;
}

getName(); /* Iven */
getName.call(object); /* Eric */
getName.apply(object); /* Eric */
  • 另一種是bind,與上面不同的是bind不會立即執行,它只是實現一個綁定的過程,返回的是一個柯里化的函數,這個柯里化的函數就是call/apply。bind只能被綁定一次。
name = 'Davy';
function bindThis(){
return this.name;
}
var getName1 = bindThis.bind({ name: "Eric" });
console.log(getName1()); /* Eric */

var getName2 = getName1.bind({ name: "Iven" });
console.log(getName2()); /* Eric */

箭頭函數在執行的時候會形成一個封閉的作用域,this與封閉作用域的this保持一致,call/apply/bind都將會被忽略。

// 瀏覽器環境 
var globalThis = this;
var arrowsFunction = () => this;
console.log(arrowsFunction() === globalObject); /* true */

作為對象的方法被調用(有一個靠近原則):在對象裡面定義了一個函數,然後通過對象去調用這個函數。

// 瀏覽器環境 
var object = {
name: 'Eric',

getName: function() {
return this.name;
}
};
console.log(object.getName()); /* Eric */


function getName2() {
return this.name;
}
object.getName = getName2;
console.log(object.getName()); /* Eric */


object.object = {
getName: getName2,
name: 'Iven'
};
console.log(object.object.getName()); /* Iven */

4:全局函數

  • setTimeout
  • setInterval
  • alert

setInterval()方法用於在指定的毫秒數後調用函數或計算表達式。

語法:setTimeout(code,millisec),參數code必需,要調用的函數後執行的JavaScript代碼串;millisec必需,在執行代碼前等待的毫秒數。

注意:setTimeout()只執行code一次,如果需要多次調用,請使用setInterval()或者讓code自身再次調用setTimeout(),也就是利用遞歸。

setInterval()方法可按照指定的週期來調用函數或計算表達式。它會不停地調用函數,指導clearInterval()被調用或者窗口被關閉。由setInterval()返回的ID值可以用作clearInterval()方法的參數。

語法:setInterval(code,millisec[,"lang"])
"

相關推薦

推薦中...