Js常見(jiàn)問(wèn)題和坑

  JavaScript 本身可以算是一門(mén)簡(jiǎn)單的語(yǔ)言,但我們也不斷用智慧和靈活的模式來(lái)改進(jìn)它敷硅。昨天我們將這些模式應(yīng)用到了 JavaScript 框架中,今天這些框架又驅(qū)動(dòng)了我們的 Web 應(yīng)用程序。很多新手開(kāi)發(fā)者被各種強(qiáng)大的 JavaScript 框架吸引進(jìn)來(lái)潭枣,但他們卻忽略了框架身后浩如星海的 JavaScript 實(shí)用技巧。本文將為你呈獻(xiàn)其中7個(gè)基礎(chǔ)知識(shí)點(diǎn)幻捏。

  1. 在 String.prototype.replace 方法中使用 /g 和 /i 標(biāo)志位

  令很多 JavaScript 初學(xué)者意外的是盆犁,字符串的 replace 方法并不會(huì) 替換所有匹配的子串——而僅僅替換第一次匹配。當(dāng)然 JavaScript 老手們都知道這里可以使用正則表達(dá)式篡九,并且需要加上一個(gè)全局標(biāo)志位(/g):

// Mistake

// 踩到坑了

var str = "David is an Arsenal fan, which means David is great";

str.replace("David", "Darren"); // "Darren is an Arsenal fan, which means David is great"

// Desired

// 符合預(yù)期

str.replace(/David/g, "Darren"); // "Darren is an Arsenal fan, which means Darren is great"

  另一個(gè)基本的邏輯錯(cuò)誤就是在大小寫(xiě)不敏感的校驗(yàn)場(chǎng)合(字母可大寫(xiě)可小寫(xiě))沒(méi)有忽略大小寫(xiě)谐岁,此時(shí) /i 標(biāo)志位就很實(shí)用:

str.replace(/david/gi, "Darren"); // "Darren will always be an Arsenal fan, which means Darren will always be great"

  (譯注:上面這段例程我沒(méi)有看懂用意榛臼,可能是注釋有誤吧……)   每個(gè) JavaScript 開(kāi)發(fā)者都曾踩過(guò)這兩個(gè)標(biāo)志位的坑——因此別忘了在適當(dāng)?shù)臅r(shí)候用上它們伊佃!

  2. 類(lèi)數(shù)組對(duì)象和 Array.prototype.slice 方法

  數(shù)組的 slice 方法通常用來(lái)從一個(gè)數(shù)組中抽取片斷。但很多開(kāi)發(fā)者不了解的是讽坏,這個(gè)方法還可以用來(lái)將“類(lèi)數(shù)組”元素(比如 arguments 參數(shù)列表锭魔、節(jié)點(diǎn)列表和屬性列表)轉(zhuǎn)換成真正的數(shù)組:(譯注:DOM 元素的屬性列表通過(guò) attributes 屬性獲取,比如 document.body.attributes路呜。)

var nodesArr = Array.prototype.slice.call(document.querySelectorAll("div"));

// "true" array of DIVs

// 得到一個(gè)由 div 元素組成的“真正的”數(shù)組

var argsArr = Array.prototype.slice.call(arguments);

// changes arguments to "true" array

// 把 arguments 轉(zhuǎn)換成一個(gè)“真正的”數(shù)組

你還可以使用一次簡(jiǎn)單的 slice 調(diào)用來(lái)克隆一個(gè)數(shù)組:

var clone = myArray.slice(0); // naive clone

// 淺克隆

 ∶耘酢(譯注:這里的參數(shù) 0 也可以省略织咧,我估計(jì) undefined 被 slice 方法自動(dòng)轉(zhuǎn)換為 0 了吧。)

  Array.prototype.slice 絕對(duì)是 JavaScript 世界中的一玫珍寶漠秋,但 JavaScript 初學(xué)者們顯然還沒(méi)有意識(shí)到它的全部潛力笙蒙。

  3. Array.prototype.sort 方法

  數(shù)組的 sort 方法 遠(yuǎn)遠(yuǎn)沒(méi)有被充分利用,而且可能比開(kāi)發(fā)者們想像的更加強(qiáng)大庆锦。很多開(kāi)發(fā)者可能覺(jué)得 sort 方法可以用來(lái)做這種事情:

[1, 3, 9, 2].sort();

// 返回 [1, 2, 3, 9]

  ……這沒(méi)錯(cuò)捅位,但它還有更強(qiáng)大的用法,比如這樣:

[

{ name: "Robin Van PurseStrings", age: 30 },

{ name: "Theo Walcott", age: 24 },

{ name: "Bacary Sagna", age: 28 }

].sort(function(obj1, obj2) {

// Ascending: first age less than the previous

// 實(shí)現(xiàn)增序排列:前者的 age 小于后者

return obj1.age - obj2.age;

});

// Returns:

// [

// { name: "Theo Walcott", age: 24 },

// { name: "Bacary Sagna", age: 28 },

// { name: "Robin Van PurseStrings", age: 30 }

// ]

  你不僅可以對(duì)簡(jiǎn)單類(lèi)型的數(shù)組項(xiàng)進(jìn)行排序搂抒,可以通過(guò)屬性來(lái)排序?qū)ο笸Р蟆H绻奶旆?wù)器端發(fā)來(lái)一段 JSON 數(shù)據(jù),而且其中的對(duì)象需要排序求晶,你可別忘了這一招焰雕!

  4. 用 length 屬性來(lái)截?cái)鄶?shù)組

  幾乎所有開(kāi)發(fā)者都踩過(guò) JavaScript 的這個(gè)坑——“傳對(duì)象只是傳引用”。開(kāi)發(fā)者們經(jīng)常會(huì)試圖 把一個(gè)數(shù)組清空芳杏,但實(shí)際上卻錯(cuò)誤地創(chuàng)建了一個(gè)新數(shù)組矩屁。

var myArray = yourArray = [1, 2, 3];

// :(

// 囧

myArray = []; // `yourArray` is still [1, 2, 3]

// `yourArray` 仍然是 [1, 2, 3]

// The right way, keeping reference

// 正確的方法是保持引用

myArray.length = 0; // `yourArray` and `myArray` both [ ]

// `yourArray` 和 `myArray`(以及其它所有對(duì)這個(gè)數(shù)組的引用)都變成 [ ] 了

  坑里的人們終于明白,原來(lái)傳對(duì)象只是在傳引用爵赵。因此當(dāng)我把 myArray 重新賦值為 [] 時(shí)吝秕,確實(shí)會(huì)創(chuàng)建出一個(gè)新的空數(shù)組,但其它對(duì)老數(shù)組的引用仍然沒(méi)變空幻!大坑八盖汀!還是換用截?cái)嗟姆椒ò煞招倌辍?/p>

  5. 使用 push 來(lái)合并數(shù)組

  在上面的第 2 節(jié)里则剃,我展示了數(shù)組的 slice 和 apply 方法所能組合出的幾個(gè)小妙招耘柱,所以對(duì)于數(shù)組方法的其它技巧如捅,你應(yīng)該已經(jīng)做好心理準(zhǔn)備了吧。這次我們使用 push 方法來(lái)合并數(shù)組:

var mergeTo = [4,5,6];

var mergeFrom = [7,8,9];

Array.prototype.push.apply(mergeTo, mergeFrom);

mergeTo; // is: [4, 5, 6, 7, 8, 9]

  這是一項(xiàng)不為人知的小技巧调煎,簡(jiǎn)單的原生方法就可以實(shí)現(xiàn)數(shù)組合并這樣的常見(jiàn)任務(wù)镜遣。(譯注:這個(gè)方法的巧妙之外不僅在于 push 方法可以接收多個(gè)參數(shù),還涉及到 apply 方法的第二個(gè)參數(shù)的用法士袄。)

  6. 高效探測(cè)功能特性和對(duì)象屬性

  很多時(shí)候開(kāi)發(fā)者們會(huì)像下面這樣來(lái)探測(cè)瀏覽器的某個(gè)特性:

if(navigator.geolocation) {

// Do some stuff

// 在這里干點(diǎn)事情

}

  當(dāng)然這可以正常工作悲关,但它并不一定有很好的效率。因?yàn)檫@個(gè)對(duì)象探測(cè)方法會(huì)在瀏覽器中初始化資源娄柳。在過(guò)去寓辱,上面的代碼片斷可能會(huì)在某些瀏覽器下導(dǎo)致內(nèi)存泄露。更好赤拒、更快的方法是檢查對(duì)象是否包含某個(gè)鍵名:

if("geolocation" in navigator) {

// Do some stuff

// 在這里干點(diǎn)事情

}

  鍵名檢查十分簡(jiǎn)單秫筏,而且可以避免內(nèi)存泄露诱鞠。另外請(qǐng)注意,如果這個(gè)屬性的值是假值这敬,那么前一種探測(cè)方式將會(huì)得到“否”的結(jié)果航夺,并不能真正探測(cè)出這個(gè)鍵名是否存在。

  7. 事件對(duì)象的 preventDefault 和 stopPropagation 方法

  很多時(shí)候崔涂,當(dāng)一個(gè)動(dòng)作元素(比如鏈接)被點(diǎn)擊時(shí)阳掐,會(huì)觸發(fā)某個(gè)功能。顯然我們并不希望點(diǎn)擊鏈接時(shí)瀏覽器順著這個(gè)鏈接跳轉(zhuǎn)冷蚂,于是我們會(huì)習(xí)慣性地使用 JavaScript 類(lèi)庫(kù)的 Event.stop 方法:

$("a.trigger").on("click", function(e) {

e.stop();

// Do more stuff

// 在這里干點(diǎn)事情

});

 $员!(譯注:不知道哪個(gè)類(lèi)庫(kù)有這個(gè)方法,估計(jì)其作用相當(dāng)于 return false; 吧蝙茶。語(yǔ)法看起來(lái)像 jQuery涮俄,但 jQuery 并沒(méi)有這個(gè)方法,而且 jQuery 是支持 e.preventDefault 和 e.stopPropagation 方法的尸闸。)

  這個(gè)懶方法有一個(gè)問(wèn)題彻亲,它不僅阻止了瀏覽器的默認(rèn)動(dòng)作,同時(shí)也阻止了事件繼續(xù)冒泡吮廉。這意味著元素上綁定的其它事件監(jiān)聽(tīng)器將不會(huì)被觸發(fā)苞尝,因?yàn)樗鼈兏揪筒恢烙惺录l(fā)生。此時(shí)不妨使用 preventDefault 吧宦芦!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末宙址,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子调卑,更是在濱河造成了極大的恐慌抡砂,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件恬涧,死亡現(xiàn)場(chǎng)離奇詭異注益,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)溯捆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)丑搔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人提揍,你說(shuō)我怎么就攤上這事啤月。” “怎么了劳跃?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵谎仲,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我刨仑,道長(zhǎng)郑诺,這世上最難降的妖魔是什么绞呈? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮间景,結(jié)果婚禮上佃声,老公的妹妹穿的比我還像新娘。我一直安慰自己倘要,他們只是感情好圾亏,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著封拧,像睡著了一般志鹃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上泽西,一...
    開(kāi)封第一講書(shū)人閱讀 52,441評(píng)論 1 310
  • 那天曹铃,我揣著相機(jī)與錄音,去河邊找鬼捧杉。 笑死陕见,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的味抖。 我是一名探鬼主播评甜,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼仔涩!你這毒婦竟也來(lái)了忍坷?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤熔脂,失蹤者是張志新(化名)和其女友劉穎佩研,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體霞揉,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡旬薯,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了零聚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片袍暴。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖隶症,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情岗宣,我是刑警寧澤蚂会,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站耗式,受9級(jí)特大地震影響胁住,放射性物質(zhì)發(fā)生泄漏趁猴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一彪见、第九天 我趴在偏房一處隱蔽的房頂上張望儡司。 院中可真熱鬧,春花似錦余指、人聲如沸捕犬。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)碉碉。三九已至,卻和暖如春淮韭,著一層夾襖步出監(jiān)牢的瞬間垢粮,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工靠粪, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蜡吧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓占键,卻偏偏與公主長(zhǎng)得像斩跌,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子捞慌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容