javascript變量作用域使用中常見(jiàn)錯(cuò)誤總結(jié)
今天在rainweb的博客上,看到了這篇非常好的文章,覺(jué)得非常有必要分享出來(lái),相信大家認(rèn)真讀完這篇文章,對(duì)js作用域的理解又會(huì)上升到一個(gè)新的臺(tái)階。
前言:javascript里變量作用域是個(gè)經(jīng)常讓人頭痛抓狂的問(wèn)題,下面通過(guò)10++個(gè)題目,對(duì)經(jīng)常遇到又容易出錯(cuò)的情況進(jìn)行了簡(jiǎn)單總結(jié),代碼樣例很短很簡(jiǎn)單
題目一
var name = 'casper'; alert(name); //毫無(wú)疑問(wèn)地輸出:casper
題目二
alert(name); //報(bào)錯(cuò):對(duì)象未定義,即使用一個(gè)壓根就不存在的變量,所以出錯(cuò)
age = 24; //這里木有錯(cuò),但age不是為定義嗎?翻下犀牛書(shū),明白了 //給一個(gè)未定義的變量賦值,會(huì)創(chuàng)建一個(gè)全局變量,相當(dāng)于:var age = 24
題目三
alert(name); //name下面才定義,這里肯定報(bào)錯(cuò)了吧?錯(cuò)!這里彈出:undefined
var name = 'casper';
解釋?zhuān)簀avascript代碼在解析的時(shí)候,都會(huì)搜索下var聲明的變量,并將其聲明提前,實(shí)際的過(guò)程如下:
var name; //光聲明name變量,但未賦值,所以為此時(shí)為:undefined
alert(name); name = 'casper';
題目四
var name = 'casper';
function show(){
alert(name);
name = 'hello'; //全局變量name的值改為'hello'
}
show(); //輸出:casper
題目五
var name = 'casper';
function show(){ alert(name); //輸出:undefined,是不是有想死的心
var name = 'hello'; //注意:與題目四相比,此處name前多了個(gè)var,
} show();
解釋?zhuān)涸诤瘮?shù)show中,name是個(gè)局部變量,題目三的原理同樣適用于此,即函數(shù)show內(nèi)部實(shí)際為
(小知識(shí)點(diǎn)補(bǔ)充:當(dāng)函數(shù)內(nèi)部存在與外部全局變量同名的局部變量,優(yōu)先使用局部變量,此處為name)
function show(){ var name; alert(name); name = 'hello'; }
題目六
var list = [1,2,3];
function show(){ if(typeof list === 'undefined')
{ list = []; }
alert(list.length);
};
show(); //結(jié)果:3,是不是一目了然= =,稍等,請(qǐng)接著看第七題
題目七
var list = [1,2,3];
function show(){
if(typeof list === 'undefined')
{ var list = []; //請(qǐng)注意,與題目六相比,這里多了個(gè)var
} alert(list.length); };
show(); //結(jié)果:0,是不是突然有了想死的沖動(dòng)
解釋?zhuān)簀avascript沒(méi)有塊級(jí)作用域(即由{}限定的作用域),函數(shù)中聲明的所有變量,無(wú)論在哪里聲明,在整個(gè)函數(shù)中都是有定義的,這點(diǎn)跟C++等灰常不同,趕緊扭轉(zhuǎn)思想與時(shí)俱進(jìn)
于是,再來(lái)看下show方法實(shí)際的內(nèi)部解析邏輯
function show(){ var list; //list為局部變量,且此處尚未賦值
if(typeof list === 'undefined'){
list = []; }
alert(list.length); };
題目八
alert(typeof show); //結(jié)果:function,請(qǐng)相信你的眼睛,你沒(méi)有看錯(cuò)
function show(){}
解釋?zhuān)簀avascript代碼解析的過(guò)程,類(lèi)似 function show() 這種形式聲明的函數(shù),跟var聲明的變量一樣,都會(huì)被提到最前面,不同的是,函數(shù)聲明跟定義同時(shí)完成,但var聲明的變量的賦值在后面才會(huì)完成
題目九
alert(typeof show); //結(jié)果:undefined,請(qǐng)?jiān)俅尾亮聊愕难劬Γ愕拇_沒(méi)有看錯(cuò)
var show = function(){};
解釋?zhuān)翰捎煤瘮?shù)定義式以及函數(shù)表達(dá)式定義函數(shù),兩者過(guò)程之間存在一些區(qū)別
函數(shù)定義式:function show(){}
函數(shù)表達(dá)式:var show = function(){}
采用函數(shù)定義式聲明的方法,函數(shù)的定義會(huì)提前;而采用函數(shù)表達(dá)式聲明的方法,函數(shù)的定義,跟采用var聲明的局部變量一樣,函數(shù)聲明會(huì)提前,但函數(shù)定義位置不變,過(guò)程如下:
var show; alert(typeof show);
show = function(){};
題目十
var data = {name:'casper'};
function data(){ alert('casper'); }
data(); //TypeError: object is not a function
是不是有砸顯示器的沖動(dòng)。。。data此時(shí)其實(shí)為{name:'casper'},把一個(gè)object當(dāng)函數(shù)調(diào)用,于是報(bào)錯(cuò)了
前面說(shuō)過(guò),函數(shù)聲明(通過(guò)函數(shù)定義式)、var聲明的變量會(huì)被提前,但是會(huì)有先后順序之分,如下:
function data(){ alert('casper');
} var data; data = {name:'casper'};
data();
略微修改下,結(jié)果就不同鳥(niǎo):
var data = {name:'casper'};
var data = function (){ //通過(guò)函數(shù)表達(dá)式聲明函數(shù)
alert('casper'); }
data(); //結(jié)果:casper
結(jié)合上文不難猜想過(guò)程如下:
var data; data = {name:'casper'};
data = function (){ alert('casper'); }
data(); //結(jié)果:casper
- JavaScript的變量作用域深入理解
- 關(guān)于javascript 回調(diào)函數(shù)中變量作用域的討論
- 理解JavaScript變量作用域更輕松
- 關(guān)于JavaScript中var聲明變量作用域的推斷
- Javascript變量作用域詳解
- JavaScript 變量作用域及閉包
- javascript權(quán)威指南 學(xué)習(xí)筆記之變量作用域分享
- 深入解析JavaScript中的變量作用域
- javascript 的變量、作用域和內(nèi)存問(wèn)題
- 簡(jiǎn)單談?wù)刯avascript中的變量、作用域和內(nèi)存問(wèn)題
- JavaScript變量作用域及內(nèi)存問(wèn)題實(shí)例分析
相關(guān)文章
利用JS實(shí)現(xiàn)scroll自定義滾動(dòng)效果詳解
這篇文章主要給大家介紹了關(guān)于利用JS如何實(shí)現(xiàn)scroll自定義滾動(dòng)效果的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-10-10
利用JS自動(dòng)打開(kāi)頁(yè)面上鏈接的實(shí)現(xiàn)代碼
今天經(jīng)過(guò)測(cè)試,實(shí)現(xiàn)了利用JS來(lái)自動(dòng)打開(kāi)頁(yè)面上的鏈接的功能,其實(shí)比較簡(jiǎn)單,就是在頁(yè)面上把鏈接列表列出來(lái),然后通過(guò)JQuery的相關(guān)控制,在框架頁(yè)中把鏈接打開(kāi),具體能做什么用,大家自己想,哈哈。2011-09-09
JavaScript ES6中類(lèi)與模塊化管理超詳細(xì)講解
JavaScript中的模塊化是指將每個(gè)js文件會(huì)被認(rèn)為單獨(dú)一個(gè)的模塊。模塊之間是互相不可見(jiàn)的。如果一個(gè)模塊需要使用另一個(gè)模塊,那么需要通過(guò)指定語(yǔ)法來(lái)引入要使用的模塊,而且只能使用引入模塊所暴露的內(nèi)容2023-01-01
基于javascript實(shí)現(xiàn)放大鏡特效
這篇文章主要為大家詳細(xì)介紹了基于javascript實(shí)現(xiàn)放大鏡特效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12
使用JavaScript實(shí)現(xiàn)一個(gè)簡(jiǎn)單的哈希映射功能
哈希表大家應(yīng)該都經(jīng)常用到吧,那么大家有沒(méi)有想過(guò)哈希表是怎么實(shí)現(xiàn)的呢,本文我們就來(lái)從一道簡(jiǎn)單的題目來(lái)了解一下哈希表的簡(jiǎn)單原理和實(shí)現(xiàn)吧2024-02-02
JavaScript常用的彈出廣告及背投廣告實(shí)現(xiàn)方法
這篇文章主要介紹了JavaScript常用的彈出廣告及背投廣告實(shí)現(xiàn)方法,實(shí)例分析了彈出廣告與背投廣告的實(shí)現(xiàn)原理與相關(guān)技巧,需要的朋友可以參考下2015-02-02
JS實(shí)現(xiàn)單行文字不間斷向上滾動(dòng)的方法
這篇文章主要介紹了JS實(shí)現(xiàn)單行文字不間斷向上滾動(dòng)的方法,以實(shí)例形式較為詳細(xì)的分析了文字滾動(dòng)效果實(shí)現(xiàn)的原理與技巧,需要的朋友可以參考下2015-01-01

