什麼是您已經看到或被絆倒的常見Javascript和/或jQuery「陷阱」?Javascript/jQuery「Gotchas」
舉個例子,有人向我指出今天早上,你必須做parseInt()
時,因爲如果你的字符串以0開始小心基數,基數將默認爲8
什麼是您已經看到或被絆倒的常見Javascript和/或jQuery「陷阱」?Javascript/jQuery「Gotchas」
舉個例子,有人向我指出今天早上,你必須做parseInt()
時,因爲如果你的字符串以0開始小心基數,基數將默認爲8
我會建議閱讀整個http://wtfjs.com/
的Javascript
parseInt('0aaa') //still returns 0
parseFloat('0.aaa') //still returns 0
這更多的人一個oops因素。在編寫switch語句時,我知道忘記在語句中放置一箇中斷,這會導致問題。
var myvar = '1'
switch (myvar) {
case '1':
alert(myvar);
case '2':
alert(myvar);
break;
}
因爲我忘了在case '1'
突破,您將收到警報的兩倍。
替換.round()
/.floor()
或.ceil()
與~~
去掉小數點後的位置很帥。
而不是
Math.floor(Math.random() * 100);
你做
~~(Math.random() * 100);
這只是短且具有更好的性能,即使!
這是一個提示/技巧,而不是一個陷阱,但仍然非常酷! – Ender 2010-10-13 18:20:10
如果添加1,我可以看到'.floor()'和'.ceil()',但它看起來不像'.round()'的替代品。也許這是* gotcha *部分? ; o) – user113716 2010-10-13 18:40:24
@帕特里克:在上下文中,爲了擺脫小數位,確實如此。 – jAndy 2010-10-13 18:47:07
道格拉斯克羅克福德的書JavaScript: The Good Parts是一個很好的閱讀有關該主題。還有的Javascript壞的和可怕的部分在裏面:)
的「這」
範圍請看下面的例子:
function myClass(message) {
this.message = message;
$('button').click(function(){
this.onClick();
});
}
myClass.prototype.onClick = function() {
alert(this.message);
}
當然,第3行不行:this
以每個功能爲基礎工作,並且第2行定義的功能將選定按鈕作爲this
而不是myClass的實例。還有一個更sneakier版本:
function myClass(message) {
this.message = message;
$('button').click(this.onClick);
}
myClass.prototype.onClick = function() {
alert(this.message);
}
這就需要正確的功能,但this
仍然是按鈕(因爲this
調用方決定,而不是由一個事實,即你是一個成員函數)。正確的解決方案是使用一箇中間變量,如self
,申請理智範圍規則到this
:
function myClass(message) {
this.message = message;
var self = this;
$('button').click(function() { self.onClick(); });
}
類型鑄造
[] == ![]
評估爲真爲晦澀原因
陣列and Properties
The length
屬性僅適用於數組上的整數鍵。例如:
var a = []; // a.length == 0
a[0] = 'first'; // a.length == 1
a['1'] = 'second'; // a.length == 2
a['x'] = 'third'; // a.length == 2 <-- 'x' does not count
雖然關於這個主題,for(in)
作品陣列上,但穿過陣列上定義的所有屬性。這意味着當您將ExtJS添加到項目中時,使用for(in)
來迭代數組的JavaScript代碼會在某些瀏覽器中突然停止工作,因爲ExtJS在不存在的情況下定義Array.prototype.filter
(這稱爲「猴子修補」)。從現在開始filter
是每個數組對象的自定義屬性,所有的循環也遍歷它。繁榮。
遍歷數組的乾淨方式是使用長度和遞增循環。或者jQuery的$.each()
。
我在Javascript中遇到的最大的WTF必須是String.replace
。
就拿這個代碼:
"An,example,of,a,comma,separated,sentence".replace(',', ' ');
這將產生由空格很好地分離,而不是,右一句?
令我驚訝的是:不,它不。它只是用一個空格替換第一個逗號,而其餘的則保持不變。如果您想要替換實際,則必須使用.replace(/,/g, ' ')
。
爲什麼該方法不被稱爲'replaceFirst'是任何人的猜測。
確實,一個常見的誤解(*實際上偏離了常態*) – 2010-10-13 19:53:21
訣竅是,根據我原來的Netscape Docs,此方法的簽名是'String.replace(regexp,newText)'在很多情況下,簡單的「字符串」被用作第一個參數,因此正則表達式全局標誌的概念被完全忽略。 – scunliffe 2010-10-15 18:20:10
幾乎每個我見過的字符串替換例程都有一個「只是第一個」模式作爲默認模式。例如,「vi」替換命令以及所有類似於「sed」的各種Unix/Linux變體都需要「g」後綴來執行「全部替換」。 Java庫具有「替換」和「替換所有」,具有相同的語義(無論如何,還有替換策略)。 – Pointy 2010-10-30 21:09:52
變量作用域和循環變量絕對是一個「陷阱」。
var lis= document.getElementsByTagName('li'),
imgs = document.getElementsByTagName('img');
for (i = 0; i < elements.length; i++)
{
elements[i].onclick = function() {
imgs[i].src = elements[i].innerHTML;
}
}
在執行的時候,imgs[i]
將是不確定的,試圖訪問imgs[i].src
時拋出一個錯誤:在一個循環中分配時,事件處理這種情況發生了很多。 elements[i]
及其innerHTML
相同。
非常真實,我昨天回答了一個問題,這是問題的原因。 – Ender 2010-10-13 20:33:40
隱含的全局是一個很大的一個:
var x = 12, y = 14;
function addOne(num)
{
x = num + 1; // since this is not declared with 'var', it is implied global
return x;
}
alert(addOne(y)); // alerts '15'
alert(addOne(x)); // alerts '16'
這是一個簡單的,和不切實際的例子,但很好地說明了問題。
Elijah Manor最近在他的博客Enterprise jQuery上發表了一篇非常好的文章。它寫在JavaScript的「陷阱」爲C#開發人員。這是一個系列文章,並且有很多好的觀點可以「讓」個人熟悉其他語言。
查看這裏:How Good C# Habits can Encourage Bad JavaScript Habits。
感謝您的提及。很高興你喜歡這篇文章。第二個帖子今天出來了,第三個帖子應該在下週出來。 – 2010-10-14 01:18:58
@Elijah - 沒問題,謝謝你的一系列精彩文章。作爲一名C#開發人員,他最近一直在做我公平的JavaScript分享,這很有幫助(尤其是錯誤的東西)。 – JasCav 2010-10-14 01:35:47
的return
聲明必須緊隨其後,或在同一行中至少開始的值:
return 4; // returns 4
return {}; // returns an empty object
return { // returns an empty object
};
return // returns undefined
{
};
阿賈克斯獲取/職位,以靜態URI可以通過IE瀏覽器中緩存。所以你需要附加一個不斷變化的參數,一個快速簡便的方法是追加new Date().getTime()
或者你可以定義:$ .ajaxSetup({cache:false});這會在任何Ajax gets/posts結尾添加日期/時間。 – Sphvn 2010-10-14 04:49:45
標記爲CW,如果它要生存結束.. – 2010-10-13 18:12:00
絕對應該是CW。 – Pointy 2010-10-13 18:14:59
感謝您的提示。 – Ender 2010-10-13 18:15:27