javascript加号"+"的二义性
單個的加號作為運算符在 JavaScript 中有三種作用。它可以表示字符串連接,例如:
varstr='hello'+'world!';
或表示數字取正值的一元運算符,例如:
varn=10;
varn2=+n;
或表示數值表達式的求和運算,例如:
varn=100;
varnn2=n+1;
三種表示法里,字符串連接與數字求和是容易出現二義性的。因為 JavaScript 中對這兩種運算的處理將依賴于數據類型,而無法從運算符上進行判讀。我們單獨地看一個表達式:
aa=a+b;
是根本無法知道它真實的含義是在求和,亦或是在做字符串連接。這在 JavaScript 引擎做語法分析時,也是無法確知的。
加號"+"帶來的主要問題與另一條規則有關。這條規則是"如果表達式中存在字符串,則優先按字符串連接進行運算"。例如:
varv1='123';
varv2=456;
//顯示結果值為字符串'123456'
alert(v1+v2);
這會在一些宿主中出現問題。例如瀏覽器中,由于 DOM 模型的許多值看起來是數字,但實際上卻是字符串。因此試圖做"和"運算,卻變成了"字符串連接"運算。下面的例子說明了這個問題:
<imgid="testPic"style="border:1solidred">
我們看到這個 id 為 testPic 的 IMG 元素(element)有一個寬度為 1 的邊框--省略了默認的單位 px(pixel,像素點)。但是如果你試圖用下面的代碼來加寬它的邊框,就會導致錯誤(一些瀏覽器忽略該值,另一些則彈出異常,還有一些瀏覽器則可能崩潰):
varel=document.getElementById('testPic');
el.style.borderWidth+=10;
因為事實上在 DOM 模型里,borderWidth 是有單位的字符串值,因此這里的值會是"1px"。JavaScript 本身并不會出錯,它會完成類似下面的運算,并將值賦給 borderWidth:
el.style.borderWidth='1px'+10;
//值為'1px10'
這時,瀏覽器的 DOM 模型無法解釋"1px10"的含義,因此出錯了。當你再次讀borderWidth 值時,它將仍是值 1px。那么,怎么證明上述的運算過程呢?下面的代碼將表明 JavaScript 運算的結果是 1px10,但賦值到 borderWidth 時,是由于 DOM 忽略掉這個錯誤的值,因此 borderWidth 沒有發生實際的修改:
alert(el.style.borderWidth='1px'+10);//值為'1px10'
這個問題追其根源,一方面在于我們允許了省略單位的樣式表寫法,另一方面也在于腳本引擎不能根據運算符來確定這里的操作是數值運算還是字符串連接。
后來 W3C 推動 XHTML 規范,試圖從第一個方面來避免這個問題,但對開發界的影響仍舊有限。因此,在瀏覽器的開發商提供的手冊中,都會盡可能地寫明每一個屬性的數據類型,以避免開發人員寫出上面這樣的代碼。在這種情況下,最正確的寫法是:
varel=document.getElementById('testPic');
//1.取原有的單位
varvalue=parseInt(el.style.borderWidth);
varunit=el.style.borderWidth.substr(value.toString().length);
//2.運算結果并附加單位
el.style.borderWidth=value+10+unit;
//如果你確知屬性采用了默認單位px,并試圖仍然省略單位值,
//那么你可以用下面這種方法(我并不推薦這樣):
//el.style.borderWidth=parseInt(el.style.borderWidth)+10;
總結
以上是生活随笔為你收集整理的javascript加号"+"的二义性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 完全理解icmp协议
- 下一篇: 方根法公式_仓储管理笔记之库存分析法:A