JavaScript的this和作用域


本文主要討論一下JS的作用域和this關鍵字。作用域,就是你的方法或者變量可訪問的區域,是他們執行的上下文。如果你見過這樣的代碼:

function someFunc() {
var _this = this;
something.on("click", function() {
console.log(_this);
});
};

你就會很好奇為什么要用this賦值給一個變量_this呢?你看完這篇文章就會清楚這個問題的答案了。

第一種作用域叫做全局作用域(Global Scope)這很容易定義,如果一個方法、變量是全局作用域的,那么它就可以從任何的地方訪問到。在瀏覽器里,全局作用域就是window對象。所以,如果你的代碼里有:

var x = 9;

你其實是在給window.x賦值為9(在瀏覽器里運行的時候)。如果你喜歡的話,也可以寫成window.x = 9,當然這不是很必要。全局作用域對象的屬性可以在代碼的任何地方訪問到。

另外的作用域就只有局部作用域了。在JavaScript里一般就是一個方法內部的作用域。比如:

function someFunction() {
var x = 5;
}
console.log(x); // undefined

變量x是在方法內部初始化的,那么就只能在方法內部訪問。

一些需要注意的地方

如果你聲明了一個變量,而且在聲明的時候忘記使用var關鍵字。那么,這個變量自動被置為全局變量。比如:

function someFunction(){
x = 5;
}

// 執行一個這個方法,完成x的全局設置
someFunction();

console.log(x); // 5

這是一個非常差的實踐。你應該盡量少的往全局作用域添加屬性。這也是為什么你會經常看到一些庫,比如jQuery會這么干:

(function() {
var jQuery = {/*全部的方法都在這里*/};
window.jQuery = jQuery;
})();

把全有的屬性、方法都放在一個方法里。然后立刻執行這個方法就會把全部的屬性和方法都綁定在了局部作用域里。最后把jQuery對象綁定到全局作用域,間接的把之前定義的屬性和方法都暴露出來方便調用。顯然我大量的減少了jQuery的代碼,但是這就是jQuery代碼如何工作的。

由於局部作用域只有通過方法的定義來實現。任何在一個方法內部定義的方法都可以訪問外部方法里定義的變量。比如:

function outer() {
var x = 5;
function inner() {
console.log(x); // 5
}

inner();
}

但是outer()方法不可以訪問inner()方法定義的任何變量。

function outer() {
var x = 5;
function inner() {
console.log(x); // 5
var y = 100;
}

inner();
console.log(y); // undefined
}

這很容易理解。但是當我們試圖要探究this關鍵字的時候就又變得復雜了。我相信很多人都遇到過這樣的問題:

${'myLink'}.on('click', function() {
console.log(this); // 指向myLink

$.ajax({
// 設置ajax相關
success: function() {
console.log(this); // 指向的是全局對象。 ???
}
});
});

this是在方法執行的時候自動賦值的變量。它的值和方法的調用方式有很大的關系。比如:

function foo() {
console.log(this); // global object
}

theApp = {};
theApp.foo = function() {
console.log(this); // 指向theApp對象
}

var link = doeument.getElementById('myLink');
link.addEventListener('click', function() {
console.log(this); // 指向link
});

MDN對第三個例子的解釋非常到位:

事件的this總是指向出發這個事件的元素對象。比如使用一個通用的事件監聽器來處理一系列的有相似事件的元素。當使用addEventListener把一個方法添加到一個元素的事件處理器的時候,這個方法的this值就被改變了。注意,this的值是從調用者里傳給方法的。

這么做:$('myLink').on('click', function() {})意味着link被點擊的時候方法就會執行。由於這個方法是處理link的事件的,所以this的值就是這個link元素。

在Ajax請求的success回調方法只是一個普通的方法。所以,當它被調用的時候this指向的是全局對象。任何對象,不是對象方法或者事件的時候會遇到的情況。

上面的原因也就是你在很多地方看到var _this = this;或者var that = this;的原因。來看一個例子:

$('myLink').on('click', function() {
console.log(this); //指向myLink
var _this = this;
$.ajax({
// ajax設置
success: function() {
console.log(this); // 指向全局對象
console.log(_this); // 指向myLink
}
});
});

原文地址:https://javascriptplayground.com/javascript-variable-scope-this/


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: