摘要:作用域是代碼的不同部分在運行期間的可見性。大多數開發者想當然地理解作用域,但毫無疑問,有它自己的說明。變量可能是全局作用域的,或者是方法作用域的。總而言之,不要重復聲明變量,使用良好命名,盡力避免在聲明前調用和執行任何東西。
原文鏈接:https://hackernoon.com/unders...
什么是作用域?就像JavaScript中的其他東西一樣,作用域并無特別之處。盡管大多數開發者并不會在上面太多時間,不過,深入理解作用域有助于你寫更干凈的應用,也有助于降低錯誤和實現更好的設計模式。
作用域是代碼的不同部分在運行期間的可見性。
大多數開發者想當然地理解作用域,但毫無疑問,JavaScript有它自己的說明。變量可能是全局作用域的,或者是方法作用域的。這也就意味著,變量存在于任何地方都能被訪問的全局,或者存在于聲明它們的方法之內。
var global = "I am global scoped" function testingFunctionScope() { var global = "I am function scoped"; console.log(global); // I am function scoped } testingFunctionScope(); console.log(global); // I am global scoped
正如你在例子中看到的那樣,盡管全局變量在方法內被賦予一個不同的值,但它只保存在這個方法中。在方法外面,那個變量有一個不同的值---在全局作用域聲明的值。
var global = "global" var anotherGlobal = "also global" function functionScope () { var global = "function scope" console.log(global) // function scope var scoped = "also function scope" function inner () { console.log(scoped); // also function scope console.log(anotherGlobal) // also global } inner(); } console.log(global) // global console.log(anotherGlobal) // also global console.log(scoped) // ReferenceError functionScope(); inner(); // ReferenceError
這是一個擁有內部函數的例子,并展示了它如何訪問父作用域的變量。正如父函數 functionScope()那樣 ,它內部聲明的每個變量只在其內部和它的內部函數中有效。
注意:絕對不要使用未聲明的變量 如果那樣做了,引擎會冒泡到父作用域尋找此變量。如果尋之不得,js會為你聲明一個。這樣你無意之中就創建了一個全局變量并擾亂了全局作用域。
另外,未定義和未聲明不是同一件事情。未定義:聲明了一個變量但沒有賦值,未聲明:變量根本還沒有被聲明。
好了,到目前為止,沒有什么特別之處,且看下面代碼如何返回:
test(); // ??? function test() { console.log("working?!"); }
驚不驚喜?確實打印出了 working?!。為了理解其中緣由我們必須探求JavaScript另一個概念。
變量提升在此我將不同于他人,我會描述什么是變量提升并解釋其弊端。困惑?好-Javascript就應該困惑。變量提升這種奇怪的行為,意味著你可以在方法聲明前調用它。
在JavaScript中,代碼執行之前變量和方法會被移至頂端。所以上面奇怪的代碼判斷,實際上變成:
function test() { console.log("working?!"); } test(); // working?!
因此,我們寫的和實際執行的并不一致。變量定義也是一樣---它們都會提升到自己作用域的頂部(用var關鍵字聲明的會;用let聲明的則不會)。變量的聲明會提升,賦值并不會。所以如果我們在一個變量賦之前使用它,得到的是undifined,并不是錯誤
var test; console.log(test) // undefined test = "working?" console.log(test) // working?
所以使用函數表達式的時候千萬小心,因為只有函數的聲明提升了。我們現在對JavaScript中的的作用域和變量提升有了基本的理解,實際上兩者有很大不同。JS代碼的整個執行過程非常不同,并且變量提升也并非大多說人所想。這更多的是我們持有的精神概念。
編譯出乎意料,JavaScript確實需要編譯。V8引擎在執行前通過將JavaScript編譯成本地機器碼而不是執行字節碼或解釋它來提升性能。實際上引擎會多線程運行代碼。其中一個線程,負責聲明所有方法和變量,所以在運行時都已存在。雖然解釋編譯過程更加簡單,對于變量提升我們創建了在代碼運行前如何組織代碼的思維導圖。
簡言之---在JS代碼實際執行前,引擎已經運行了整個腳本并在它們的作用域中聲明了所有的變量和方法。所以在運行時,它們已經存在,變量提升并非什么黑魔法。如果你理解了這個,你就超過了其他90%的JavaScript開發者。
總結JavaScript的作用域還有很多需要學習。為了縮短篇幅讓大家有個基本的理解,我甚至都沒有提LHS和RHS。如果你搞不清楚你所做的事情,JavaScript絕對驚喜多多(bug啊)。總而言之,不要重復聲明變量,使用良好命名,盡力避免在聲明前調用和執行任何東西。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/94971.html
摘要:當面試中讓我解釋一下閉包時我懵逼了。這個解釋開始可能有點晦澀,讓我們抽絲剝繭摘下閉包的真面目。此文不詳述作用域有專門的主題闡述,不過作用域是理解閉包原理的基礎。這才是閉包的真正便利之處。閉包使用不當就會很坑。 原文鏈接 為什么深度學習JavaScript? JavaScript如今是最流行的編程語言之一。它運行在瀏覽器、服務器、移動設備、桌面應用,也可能包括冰箱。無需我舉其他再多不相干...
摘要:比如,我們可以監聽事件由實例發出,然后在任何瀏覽器中就是變化的時候都會得到通知,如下所示每一個作用域對象都會有這個方法,可以用來注冊一個作用域事件的偵聽器。這個函數所扮演的偵聽器在被調用時會有一個對象作為第一個參數。 上一篇:【譯】《精通使用AngularJS開發Web App》(二) 下一篇:【譯】《精通使用AngularJS開發Web App》(四) 書名:Mastering W...
摘要:原文鏈接原文作者你想知道的關于作用域的一切譯中有許多章節是關于的但是對于初學者來說甚至是一些有經驗的開發者這些有關作用域的章節既不直接也不容易理解這篇文章的目的就是為了幫助那些想更深一步學習了解作用域的開發者尤其是當他們聽到一些關于作用域的 原文鏈接: Everything you wanted to know about JavaScript scope原文作者: Todd Mott...
摘要:最近在上看到一篇關于變量提升的文章,原文在此。對于剛入門的開發者時常難以理解變量方法提升的獨特行為。接下來我們要談論,,聲明,那么先了解變量提升就顯得更為重要了。在進入作用域和不能訪問的這段時間,我們稱為暫時性死區。 showImg(https://segmentfault.com/img/bV0Nsd?w=800&h=450); 最近在Medium上看到一篇關于變量提升的文章,原文在...
摘要:關鍵字會實例化一個新的對象實例,并在執行構造函數時將指向該實例。原文鏈接譯是什么對象的內部工作原理 原文鏈接:What is this? The Inner Workings of JavaScript Objects (需要梯子) 原文作者:Eric Elliott 譯文永久鏈接:【譯】什么是 this?JavaScript 對象的內部工作原理 譯者:士心 翻譯目的:函數動...
閱讀 3479·2023-04-25 22:45
閱讀 1282·2021-11-11 16:54
閱讀 2790·2019-08-30 15:44
閱讀 3190·2019-08-30 15:44
閱讀 1646·2019-08-30 13:55
閱讀 941·2019-08-29 18:45
閱讀 1195·2019-08-29 17:25
閱讀 1007·2019-08-29 12:59