欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Javascript學(xué)習(xí)筆記之函數(shù)篇(六) : 作用域與命名空間

 更新時(shí)間:2014年11月23日 11:54:59   投稿:hebedich  
本文主要講述了javascript中作用域和命名空間的區(qū)別,十分的詳細(xì),這里推薦給大家,希望小伙伴能有所收獲

在之前的介紹中,我們已經(jīng)知道 Javascript 沒(méi)有塊級(jí)作用,只有函數(shù)級(jí)作用域。

復(fù)制代碼 代碼如下:

function test() { // a scope
    for(var i = 0; i < 10; i++) { // not a scope
        // count
    }
    console.log(i); // 10
}

Javascript 中也沒(méi)有顯示的命名空間,這就意味著一切都定義在全局作用域中。每一次引用一個(gè)變量時(shí),Javascript 會(huì)往上遍歷整個(gè)全局作用域直到找到該變量。如果遍歷完整個(gè)全局作用域仍然沒(méi)有找到該變量,則拋出一個(gè) ReferenceError 錯(cuò)誤。

請(qǐng)輸入圖片描述

隱式全局變量

復(fù)制代碼 代碼如下:

// script A
foo = '42';
// script B
var foo = '42'

上面的兩個(gè)例子產(chǎn)生不一樣的效果。第一個(gè)將在全局作用域中定義變量 foo,而第二個(gè)則在當(dāng)前作用域定義變量 foo。
我們一定要注意,如果不使用關(guān)鍵字 var 將會(huì)帶來(lái)意想不到的影響。

復(fù)制代碼 代碼如下:

// global scope
var foo = 42;
function test() {
    // local scope
    foo = 21;
}
test();
foo; // 21

由于在函數(shù) test 內(nèi)沒(méi)用 var 來(lái)定義變量 foo,所以將覆蓋函數(shù)外部的全局變量 foo。盡管看上去不是什么大問(wèn)題,但是如果有成千上萬(wàn)行代碼時(shí),這將是個(gè)難以追蹤的 bug。

復(fù)制代碼 代碼如下:

// global scope
var items = [/* some list */];
for(var i = 0; i < 10; i++) {
    subLoop();
}
function subLoop() {
    // scope of subLoop
    for(i = 0; i < 10; i++) { // missing var statement
        // do amazing stuff!
    }
}

上例中,外部的循環(huán)將會(huì)在執(zhí)行第一次的時(shí)候就停止,這是因?yàn)?subloop 函數(shù)內(nèi)部的變量 i 將會(huì)覆蓋外部的全局變量 i。我們只需要在函數(shù)內(nèi)部加上一個(gè) var 就可以避免這個(gè)錯(cuò)誤,所以我們?cè)诙x變量時(shí)一定不要忘記加上關(guān)鍵字 var。除非我們確實(shí)希望對(duì)外部的全局變量造成影響。

局部變量

Javascript 中局部變量只可以通過(guò)兩個(gè)方式產(chǎn)生,一是通過(guò)關(guān)鍵字 var 來(lái)聲明,一是作為函數(shù)的形參。

復(fù)制代碼 代碼如下:

// global scope
var foo = 1;
var bar = 2;
var i = 2;
function test(i) {
    // local scope of the function test
    i = 5;
    var foo = 3;
    bar = 4;
}
test(10);

此時(shí),函數(shù) test 內(nèi)部的變量 i 和 foo 是局部變量,而 bar 則會(huì)覆蓋外部的全局變量 bar。

提升(Hoisting)

Javascript 將會(huì)提升變量聲明,這就意味著 var 表達(dá)式和函數(shù)聲明都將被提升到作用域的頂部。

復(fù)制代碼 代碼如下:

bar();
var bar = function() {};
var someValue = 42;
test();
function test(data) {
    if (false) {
        goo = 1;
    } else {
        var goo = 2;
    }
    for(var i = 0; i < 100; i++) {
        var e = data[i];
    }
}

上面的代碼在運(yùn)行之前, var 表達(dá)式和函數(shù) test 的聲明都將提升至頂部,因此程序?qū)⒄_\(yùn)行并不會(huì)報(bào)錯(cuò)。

復(fù)制代碼 代碼如下:

// var statements got moved here
var bar, someValue; // default to 'undefined'
// the function declaration got moved up too
function test(data) {
    var goo, i, e; // missing block scope moves these here
    if (false) {
        goo = 1;
    } else {
        goo = 2;
    }
    for(i = 0; i < 100; i++) {
        e = data[i];
    }
}
bar(); // fails with a TypeError since bar is still 'undefined'
someValue = 42; // assignments are not affected by hoisting
bar = function() {};
test();

由于 Javascript 沒(méi)有塊級(jí)作用域,這不僅將提升 var 表達(dá)式,同時(shí)也會(huì)使得 if 結(jié)構(gòu)變得不夠直觀。
在上例中,盡管看上去 if 在對(duì)全局變量 goo 進(jìn)行操作,實(shí)際上,由于變量 goo 被提升,所以修改的是局部變量。
如果沒(méi)有對(duì)提升規(guī)則有所了解,你可能會(huì)認(rèn)為下面的代碼將會(huì)拋出 ReferenceError 錯(cuò)誤。

復(fù)制代碼 代碼如下:

// check whether SomeImportantThing has been initialized
if (!SomeImportantThing) {
    var SomeImportantThing = {};
}

當(dāng)然上面的代碼是沒(méi)有錯(cuò)誤的,因?yàn)樵诖a在運(yùn)行前,var 表達(dá)式已經(jīng)被提升到頂部。

復(fù)制代碼 代碼如下:

var SomeImportantThing;
// other code might initialize SomeImportantThing here, or not
// make sure it's there
if (!SomeImportantThing) {
    SomeImportantThing = {};
}

這里要推薦下 @nightire 凡哥的博文 《理解 JavaScript(二)》,里面對(duì)提升的講解非常透徹。
名稱解析順序

當(dāng)嘗試在一個(gè)函數(shù)作用域內(nèi)訪問(wèn)一個(gè) foo 變量時(shí),Javascript 將會(huì)按照下面的順序查找:

當(dāng)前作用域內(nèi)是否有 var foo 的定義。
函數(shù)形參中是否有 foo 變量。
函數(shù)自身的名稱是否為 foo。
跳到外層定義域,再?gòu)牡谝徊块_始查找起。
命名空間

一個(gè)最常見的問(wèn)題就是命名沖突,這是因?yàn)?Javascript 只有一個(gè)全局作用域所帶來(lái)的。但這個(gè)問(wèn)題可以通過(guò)匿名的外部函數(shù)解決。

復(fù)制代碼 代碼如下:

(function() {
    // a self contained "namespace"
    window.foo = function() {
        // an exposed closure
    };
})(); // execute the function immediately

上例中的匿名函數(shù)被認(rèn)為是表達(dá)式,所以它們會(huì)被執(zhí)行。

復(fù)制代碼 代碼如下:

( // evaluate the function inside the parentheses
function() {}
) // and return the function object
() // call the result of the evaluation

當(dāng)然我們也可以用其他方式來(lái)調(diào)用函數(shù)表達(dá)式,不同的結(jié)構(gòu),但是同樣的效果。

復(fù)制代碼 代碼如下:

// A few other styles for directly invoking the
!function(){}()
+function(){}()
(function(){}());
// and so on...

總結(jié)

建議大家使用匿名的外部函數(shù)來(lái)將代碼封裝到空間內(nèi),這樣不僅可以解決命名空間的沖突,同時(shí)也有利于程序的模塊化。
此外,使用全局變量不是一個(gè)好習(xí)慣,這將帶來(lái)高成本的維護(hù)代價(jià)而且容易產(chǎn)生錯(cuò)誤。

命名空間同類型、函數(shù)、變量、模板等都屬于實(shí)體(entity)。
實(shí)體的主要的共性是,可以具有名稱。(此外,標(biāo)簽也可以具有名稱,但它不是實(shí)體。)
而命名空間作用域是作用域中的一類統(tǒng)稱,和塊作用域、類作用域、函數(shù)原型作用域、函數(shù)作用域(僅對(duì)標(biāo)簽有效)并列。命名空間內(nèi)聲明的名稱在命名空間作用域中。全局名稱被認(rèn)為在隱含的全局命名空間作用域中。

命名空間作用確實(shí)就是作用域,但是,他又不同于簡(jiǎn)單的作用域,你可以分多次在多處聲明同一個(gè)命名空間,但是里面的內(nèi)容不能重定義,他們最終都會(huì)合成一個(gè)命名空間,就像std,到處宏定義

相關(guān)文章

  • js arguments對(duì)象應(yīng)用介紹

    js arguments對(duì)象應(yīng)用介紹

    本文將詳細(xì)介紹js arguments對(duì)象的使用方法,需要了解更多的朋友可以參考下
    2012-11-11
  • javascript創(chuàng)建對(duì)象的幾種模式介紹

    javascript創(chuàng)建對(duì)象的幾種模式介紹

    下面小編就為大家?guī)?lái)一篇javascript創(chuàng)建對(duì)象的幾種模式介紹。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考
    2016-05-05
  • 詳解js加減乘除精確計(jì)算

    詳解js加減乘除精確計(jì)算

    這篇文章主要介紹了js加減乘除精確計(jì)算,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • js 判斷checkbox是否選中的操作方法

    js 判斷checkbox是否選中的操作方法

    大家在很多場(chǎng)合也許會(huì)遇到判斷頁(yè)面是否有元素選中,下面介紹的是利用js判斷是否選中CheckBox的方法
    2012-11-11
  • JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記2 js基礎(chǔ)語(yǔ)法

    JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記2 js基礎(chǔ)語(yǔ)法

    這一篇復(fù)習(xí)一下ECMAScript規(guī)范中的基礎(chǔ)語(yǔ)法,英文好的朋友可以直接閱讀官方文檔。JavaScript本質(zhì)上也是一種類C語(yǔ)言,熟悉C語(yǔ)言的朋友,可以非常輕松的閱讀這篇文章,甚至都可以跳過(guò),不過(guò)建議你最好還是看一看,在介紹的同時(shí),我可能會(huì)引用一些自認(rèn)為不易理解且比較流行的用法。
    2012-10-10
  • 深入理解JavaScript中的對(duì)象

    深入理解JavaScript中的對(duì)象

    這篇文章主要介紹了深入理解JavaScript中的對(duì)象,是JS入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-06-06
  • javascript編程必備_JS語(yǔ)法字典

    javascript編程必備_JS語(yǔ)法字典

    網(wǎng)友整理的107條javascript語(yǔ)法字典,方便經(jīng)常使用js編程的朋友
    2008-06-06
  • javascript常用方法匯總

    javascript常用方法匯總

    本文給大家匯總了一些自己整理的在項(xiàng)目中經(jīng)常能夠用到的javascript小方法,基本都是短小精悍型,方便大家快速開發(fā)。
    2014-12-12
  • JavaScript DOM元素尺寸和位置

    JavaScript DOM元素尺寸和位置

    這篇文章主要介紹了JavaScript DOM元素尺寸和位置,需要的朋友可以參考下
    2015-04-04
  • JavaScript對(duì)內(nèi)存分配及管理機(jī)制詳細(xì)解析

    JavaScript對(duì)內(nèi)存分配及管理機(jī)制詳細(xì)解析

    本文主要講述了JavaScript的垃圾回收原理和具體的過(guò)程。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助
    2013-11-11

最新評(píng)論