javascript加號(hào)"+"的二義性說(shuō)明
單個(gè)的加號(hào)作為運(yùn)算符在 JavaScript 中有三種作用。它可以表示字符串連接,例如:
var str = 'hello ' + 'world!';
或表示數(shù)字取正值的一元運(yùn)算符,例如:
var n = 10;
var n2 = +n;
或表示數(shù)值表達(dá)式的求和運(yùn)算,例如:
var n = 100;
var nn2 = n + 1;
三種表示法里,字符串連接與數(shù)字求和是容易出現(xiàn)二義性的。因?yàn)?JavaScript 中對(duì)這兩種運(yùn)算的處理將依賴于數(shù)據(jù)類型,而無(wú)法從運(yùn)算符上進(jìn)行判讀。我們單獨(dú)地看一個(gè)表達(dá)式:
aa = a + b;
是根本無(wú)法知道它真實(shí)的含義是在求和,亦或是在做字符串連接。這在 JavaScript 引擎做語(yǔ)法分析時(shí),也是無(wú)法確知的。
加號(hào)"+"帶來(lái)的主要問(wèn)題與另一條規(guī)則有關(guān)。這條規(guī)則是"如果表達(dá)式中存在字符串,則優(yōu)先按字符串連接進(jìn)行運(yùn)算"。例如:
var v1 = '123';
var v2 = 456;
//顯示結(jié)果值為字符串'123456'
alert( v1 + v2 );
這會(huì)在一些宿主中出現(xiàn)問(wèn)題。例如瀏覽器中,由于 DOM 模型的許多值看起來(lái)是數(shù)字,但實(shí)際上卻是字符串。因此試圖做"和"運(yùn)算,卻變成了"字符串連接"運(yùn)算。下面的例子說(shuō)明了這個(gè)問(wèn)題:
<img id="testPic" style="border: 1 solid red">
我們看到這個(gè) id 為 testPic 的 IMG 元素(element)有一個(gè)寬度為 1 的邊框--省略了默認(rèn)的單位 px(pixel,像素點(diǎn))。但是如果你試圖用下面的代碼來(lái)加寬它的邊框,就會(huì)導(dǎo)致錯(cuò)誤(一些瀏覽器忽略該值,另一些則彈出異常,還有一些瀏覽器則可能崩潰):
var el = document.getElementById('testPic');
el.style.borderWidth += 10;
因?yàn)槭聦?shí)上在 DOM 模型里,borderWidth 是有單位的字符串值,因此這里的值會(huì)是"1px"。JavaScript 本身并不會(huì)出錯(cuò),它會(huì)完成類似下面的運(yùn)算,并將值賦給 borderWidth:
el.style.borderWidth = '1px' + 10;
//值為 '1px10'
這時(shí),瀏覽器的 DOM 模型無(wú)法解釋"1px10"的含義,因此出錯(cuò)了。當(dāng)你再次讀borderWidth 值時(shí),它將仍是值 1px。那么,怎么證明上述的運(yùn)算過(guò)程呢?下面的代碼將表明 JavaScript 運(yùn)算的結(jié)果是 1px10,但賦值到 borderWidth 時(shí),是由于 DOM 忽略掉這個(gè)錯(cuò)誤的值,因此 borderWidth 沒(méi)有發(fā)生實(shí)際的修改:
alert( el.style.borderWidth = '1px' + 10 );//值為 '1px10'
這個(gè)問(wèn)題追其根源,一方面在于我們?cè)试S了省略單位的樣式表寫(xiě)法,另一方面也在于腳本引擎不能根據(jù)運(yùn)算符來(lái)確定這里的操作是數(shù)值運(yùn)算還是字符串連接。
后來(lái) W3C 推動(dòng) XHTML 規(guī)范,試圖從第一個(gè)方面來(lái)避免這個(gè)問(wèn)題,但對(duì)開(kāi)發(fā)界的影響仍舊有限。因此,在瀏覽器的開(kāi)發(fā)商提供的手冊(cè)中,都會(huì)盡可能地寫(xiě)明每一個(gè)屬性的數(shù)據(jù)類型,以避免開(kāi)發(fā)人員寫(xiě)出上面這樣的代碼。在這種情況下,最正確的寫(xiě)法是:
var el = document.getElementById('testPic');
// 1.取原有的單位
var value = parseInt(el.style.borderWidth);
var unit = el.style.borderWidth.substr(value.toString().length);
// 2.運(yùn)算結(jié)果并附加單位
el.style.borderWidth = value + 10 + unit;
//如果你確知屬性采用了默認(rèn)單位 px,并試圖仍然省略單位值,
//那么你可以用下面這種方法(我并不推薦這樣):
// el.style.borderWidth = parseInt(el.style.borderWidth) + 10;
相關(guān)文章
js給網(wǎng)頁(yè)加上背景音樂(lè)及選擇音效的方法
這篇文章主要介紹了js給網(wǎng)頁(yè)加上背景音樂(lè)及選擇音效的方法,涉及javascript操作音頻的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03
jquery單行文字向上滾動(dòng)效果的實(shí)現(xiàn)代碼
這篇文章主要介紹了jquery單行文字向上滾動(dòng)效果的具體實(shí)現(xiàn),此效果適應(yīng)于很多場(chǎng)景,會(huì)的不會(huì)的都要學(xué)習(xí)下啊2014-09-09
js帶點(diǎn)自動(dòng)圖片輪播幻燈片特效代碼分享
這篇文章主要為大家詳細(xì)介紹了js帶點(diǎn)自動(dòng)圖片輪播幻燈片特效,圖片輪播效果特別適合做產(chǎn)品展示,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2015-09-09
javascript獲取四位數(shù)字或者字母的隨機(jī)數(shù)
這篇文章主要介紹了javascript獲取四位數(shù)字或者字母的隨機(jī)數(shù),需要的朋友可以參考下2015-01-01
初步使用bootstrap快速創(chuàng)建頁(yè)面
初步嘗試使用Express搭建了一個(gè)Web框架,那么接下來(lái)就是要在該框架下寫(xiě)上自己的頁(yè)面,快速創(chuàng)建頁(yè)面這里選擇了bootstrap前端框架,通過(guò)它即使你不太懂前端設(shè)計(jì),寫(xiě)出來(lái)的頁(yè)面也不會(huì)太難看,感興趣的小伙伴們可以參考一下2016-03-03
用javascript取得傳遞參數(shù)的個(gè)數(shù)的代碼
用javascript取得傳遞參數(shù)的個(gè)數(shù)的代碼...2007-10-10

