摘要:訪問(wèn)屬性是通過(guò)操作符完成的,但這要求屬性名必須是一個(gè)有效的變量名小紅的屬性名不是一個(gè)有效的變量,就需要用括起來(lái)。閉包應(yīng)用封裝私有變量箭頭函數(shù)箭頭函數(shù)相當(dāng)于匿名函數(shù),并且簡(jiǎn)化了函數(shù)定義。
數(shù)據(jù)類(lèi)型
NAN
NaN === NaN; // false
唯一能判斷NaN的方法是通過(guò)isNaN()函數(shù):
isNaN(NaN); // true
浮點(diǎn)數(shù)的相等比較:
1 / 3 === (1 - 2 / 3); // false
這不是JavaScript的設(shè)計(jì)缺陷。浮點(diǎn)數(shù)在運(yùn)算過(guò)程中會(huì)產(chǎn)生誤差,因?yàn)橛?jì)算機(jī)無(wú)法精確表示無(wú)限循環(huán)小數(shù)。要比較兩個(gè)浮點(diǎn)數(shù)是否相等,只能計(jì)算它們之差的絕對(duì)值,看是否小于某個(gè)閾值:
Math.abs(1 / 3 - (1 - 2 / 3)) < 0.0000001; // true
避免使用new Array(1, 2, 3); // 創(chuàng)建了數(shù)組[1, 2, 3]方式
字符串
需要特別注意的是,字符串是不可變的
如果對(duì)字符串的某個(gè)索引賦值,不會(huì)有任何錯(cuò)誤,但是,也沒(méi)有任何效果:
var s = "Test"; s[0] = "X"; alert(s); // s仍然為"Test"
JavaScript為字符串提供了一些常用方法,注意,調(diào)用這些方法本身不會(huì)改變?cè)凶址膬?nèi)容,而是返回一個(gè)新字符串
數(shù)組大多數(shù)其他編程語(yǔ)言不允許直接改變數(shù)組的大小,越界訪問(wèn)索引會(huì)報(bào)錯(cuò)。然而,JavaScript的Array卻不會(huì)有任何錯(cuò)誤。在編寫(xiě)代碼時(shí),不建議直接修改Array的大小,訪問(wèn)索引時(shí)要確保索引不會(huì)越界。
對(duì)原數(shù)組進(jìn)行操作的方法和返回新數(shù)組的方法
原數(shù)組:
pop/push,unshift/shift
sort
reverse
splice
新數(shù)組:
slice
concat
join返回的是新的字符串
擴(kuò)展:數(shù)組扁平化的幾種方法
var myArray = [[1, 2],[3, 4, 5], [6, 7, 8, 9]];
使用concat()和apply()
var myNewArray = [].concat.apply([], myArray); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
使用reduce()
var myNewArray = myArray.reduce(function(prev, curr) { return prev.concat(curr); }); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
MSDN reduce 方法
使用 ES6 的展開(kāi)運(yùn)算符
var myNewArray4 = [].concat(...myArray); console.log(myNewArray4); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
MDN 展開(kāi)運(yùn)算符
最后這個(gè)方法返回的是字符串
myArray.join(",") //"1,2,3,4,5,6,7,8,9"
請(qǐng)注意,for ... in對(duì)Array的循環(huán)得到的是String而不是Number
對(duì)象注意,最后一個(gè)鍵值對(duì)不需要在末尾加,,如果加了,有的瀏覽器(如低版本的IE)將報(bào)錯(cuò)。
訪問(wèn)屬性是通過(guò).操作符完成的,但這要求屬性名必須是一個(gè)有效的變量名
var xiaohong = { name: "小紅", "middle-school": "No.1 Middle School" };
xiaohong的屬性名middle-school不是一個(gè)有效的變量,就需要用""括起來(lái)。訪問(wèn)這個(gè)屬性也無(wú)法使用.操作符,必須用["xxx"]來(lái)訪問(wèn):
xiaohong["middle-school"]; // "No.1 Middle School" xiaohong["name"]; // "小紅" xiaohong.name; // "小紅"
訪問(wèn)不存在的屬性不報(bào)錯(cuò),而是返回undefined
函數(shù)
小心你的return語(yǔ)句
如果把return語(yǔ)句拆成兩行:
function foo() { return { name: "foo" }; } foo(); // undefined
要小心了,由于JavaScript引擎在行末自動(dòng)添加分號(hào)的機(jī)制,上面的代碼實(shí)際上變成了:
function foo() { return; // 自動(dòng)添加了分號(hào),相當(dāng)于return undefined; { name: "foo" }; // 這行語(yǔ)句已經(jīng)沒(méi)法執(zhí)行到了 }
所以正確的多行寫(xiě)法是:
function foo() { return { // 這里不會(huì)自動(dòng)加分號(hào),因?yàn)閧表示語(yǔ)句尚未結(jié)束 name: "foo" }; }
變量提升
由于JavaScript的這一怪異的“特性”,我們?cè)诤瘮?shù)內(nèi)部定義變量時(shí),請(qǐng)嚴(yán)格遵守“在函數(shù)內(nèi)部首先申明所有變量”這一規(guī)則。
閉包應(yīng)用:封裝私有變量
function create_counter(initial) { var x = initial || 0; return { inc: function () { x += 1; return x; } } }
箭頭函數(shù)
箭頭函數(shù)相當(dāng)于匿名函數(shù),并且簡(jiǎn)化了函數(shù)定義。箭頭函數(shù)有兩種格式,一種只包含一個(gè)表達(dá)式,連{ ... }和return都省略掉了。還有一種可以包含多條語(yǔ)句,這時(shí)候就不能省略{ ... }和return
返回對(duì)象:
// SyntaxError: x => { foo: x } // ok: x => ({ foo: x })
箭頭函數(shù)完全修復(fù)了this的指向,箭頭函數(shù)內(nèi)部的this是詞法作用域,由上下文確定
擴(kuò)展:裝飾器
現(xiàn)在假定我們想統(tǒng)計(jì)一下代碼一共調(diào)用了多少次parseInt(),可以把所有的調(diào)用都找出來(lái),然后手動(dòng)加上count += 1,不過(guò)這樣做太傻了。最佳方案是用我們自己的函數(shù)替換掉默認(rèn)的parseInt():
var count = 0; var oldParseInt = parseInt; // 保存原函數(shù) window.parseInt = function () { count += 1; return oldParseInt.apply(null, arguments); // 調(diào)用原函數(shù) }; // 測(cè)試: parseInt("10"); parseInt("20"); parseInt("30"); count; // 3對(duì)象
需要遵守的規(guī)則
不要使用new Number()、new Boolean()、new String()創(chuàng)建包裝對(duì)象;
用parseInt()或parseFloat()來(lái)轉(zhuǎn)換任意類(lèi)型到number;
用String()來(lái)轉(zhuǎn)換任意類(lèi)型到string,或者直接調(diào)用某個(gè)對(duì)象的toString()方法;
通常不必把任意類(lèi)型轉(zhuǎn)換為boolean再判斷,因?yàn)榭梢灾苯訉?xiě)if (myVar) {...};
typeof操作符可以判斷出number、boolean、string、function和undefined;
判斷Array要使用Array.isArray(arr);
判斷null請(qǐng)使用myVar === null;
判斷某個(gè)全局變量是否存在用typeof window.myVar === "undefined";
函數(shù)內(nèi)部判斷某個(gè)變量是否存在用typeof myVar === "undefined"。
獲取時(shí)間戳
if (Date.now) { alert(Date.now()); // 老版本IE沒(méi)有now()方法 } else { alert(new Date().getTime()); }
JSON.stringify()
格式化
var xiaoming = { name: "小明", age: 14, gender: true, height: 1.65, grade: null, "middle-school": ""W3C" Middle School", skills: ["JavaScript", "Java", "Python", "Lisp"] }; undefined JSON.stringify(xiaoming, null, " "); "{ "name": "小明", "age": 14, "gender": true, "height": 1.65, "grade": null, "middle-school": ""W3C" Middle School", "skills": [ "JavaScript", "Java", "Python", "Lisp" ] }"
篩選數(shù)據(jù)
第二個(gè)參數(shù)用于控制如何篩選對(duì)象的鍵值,如果我們只想輸出指定的屬性,可以傳入Array:
JSON.stringify(xiaoming, ["name", "height"], " ");
"{ "name": "小明", "height": 1.65 }"
也可以傳入函數(shù)進(jìn)行處理
瀏覽器
獲取UA
function whatBrowser() { document.Browser.Name.value=navigator.appName; document.Browser.Version.value=navigator.appVersion; document.Browser.Code.value=navigator.appCodeName; document.Browser.Agent.value=navigator.userAgent; }
請(qǐng)注意,navigator的信息可以很容易地被用戶(hù)修改,所以JavaScript讀取的值不一定是正確的
cookie安全問(wèn)題
由于JavaScript能讀取到頁(yè)面的Cookie,而用戶(hù)的登錄信息通常也存在Cookie中,這就造成了巨大的安全 隱患。為了解決這個(gè)問(wèn)題,服務(wù)器在設(shè)置Cookie時(shí)可以使用httpOnly,設(shè)定了httpOnly的Cookie將不能被JavaScript讀取。這個(gè)行為由瀏覽器實(shí)現(xiàn),主流瀏覽器均支持httpOnly選項(xiàng),IE從IE6 SP1開(kāi)始支持。
為了確保安全,服務(wù)器端在設(shè)置Cookie時(shí),應(yīng)該始終堅(jiān)持使用httpOnly。
按字符串順序重新排序DOM節(jié)點(diǎn)
- Scheme
- JavaScript
- Python
- Ruby
- Haskell
var ol = document.getElementById("test-list"), lis = [].slice.call(ol.children); lis.sort((a,b)=> a.innerText.toUpperCase() > b.innerText.toUpperCase()); lis.forEach(x=>{ol.appendChild(x)})
children屬性時(shí)刻都在變化
當(dāng)你遍歷一個(gè)父節(jié)點(diǎn)的子節(jié)點(diǎn)并進(jìn)行刪除操作時(shí),要注意,children屬性是一個(gè)只讀屬性,并且它在子節(jié)點(diǎn)變化時(shí)會(huì)實(shí)時(shí)更新。
例如,對(duì)于如下HTML結(jié)構(gòu):
First
Second
當(dāng)我們用如下代碼刪除子節(jié)點(diǎn)時(shí):
var parent = document.getElementById("parent"); parent.removeChild(parent.children[0]); parent.removeChild(parent.children[1]); // <-- 瀏覽器報(bào)錯(cuò)
瀏覽器報(bào)錯(cuò):parent.children[1]不是一個(gè)有效的節(jié)點(diǎn)。原因就在于,當(dāng)
First
節(jié)點(diǎn)被刪除后,parent.children的節(jié)點(diǎn)數(shù)量已經(jīng)從2變?yōu)榱?,索引[1]已經(jīng)不存在了。
擴(kuò)展練習(xí)
把與Web開(kāi)發(fā)技術(shù)不相關(guān)的節(jié)點(diǎn)刪掉
var parent = document.getElementById("test-list"); var children = [].slice.call(parent.children); //Array.prototype.slice.call() children.forEach((element) => { for(var s of ["Swift", "ANSI C", "DirectX"]){ if(element.innerText == s){ parent.removeChild(element); } } });事件
需要特別注意的是,下面這種寫(xiě)法是無(wú)效的:
// 綁定事件: a.click(function () { alert("hello!"); }); // 解除綁定: a.off("click", function () { alert("hello!"); });
這是因?yàn)閮蓚€(gè)匿名函數(shù)雖然長(zhǎng)得一模一樣,但是它們是兩個(gè)不同的函數(shù)對(duì)象,off("click", function () {...})無(wú)法移除已綁定的第一個(gè)匿名函數(shù)。
為了實(shí)現(xiàn)移除效果,可以使用off("click")一次性移除已綁定的click事件的所有處理函數(shù)。
同理,無(wú)參數(shù)調(diào)用off()一次性移除已綁定的所有類(lèi)型的事件處理函數(shù)。
事件觸發(fā)條件
一個(gè)需要注意的問(wèn)題是,事件的觸發(fā)總是由用戶(hù)操作引發(fā)的,但是,如果用JavaScript代碼去改動(dòng),將不會(huì)觸發(fā)change事件
有些時(shí)候,我們希望用代碼觸發(fā)change事件,可以直接調(diào)用無(wú)參數(shù)的change()方法來(lái)觸發(fā)該事件
var input = $("#test-input"); input.val("change it!"); input.change(); // 觸發(fā)change事件
input.change()相當(dāng)于input.trigger("change"),它是trigger()方法的簡(jiǎn)寫(xiě)。
瀏覽器安全限制
在瀏覽器中,有些JavaScript代碼只有在用戶(hù)觸發(fā)下才能執(zhí)行,例如,window.open()函數(shù):
// 無(wú)法彈出新窗口,將被瀏覽器屏蔽: $(function () { window.open("/"); });
這些“敏感代碼”只能由用戶(hù)操作來(lái)觸發(fā):
var button1 = $("#testPopupButton1"); var button2 = $("#testPopupButton2"); function popupTestWindow() { window.open("/"); } button1.click(function () { popupTestWindow(); }); button2.click(function () { // 不立刻執(zhí)行popupTestWindow(),100毫秒后執(zhí)行: setTimeout(popupTestWindow, 100); });
當(dāng)用戶(hù)點(diǎn)擊button1時(shí),click事件被觸發(fā),由于popupTestWindow()在click事件處理函數(shù)內(nèi)執(zhí)行,這是瀏覽器允許的,而button2的click事件并未立刻執(zhí)行popupTestWindow(),延遲執(zhí)行的popupTestWindow()將被瀏覽器攔截。
Ajaxopen方法的第三個(gè)參數(shù)
千萬(wàn)不要把第三個(gè)參數(shù)指定為false,否則瀏覽器將停止響應(yīng),直到AJAX請(qǐng)求完成。
跨域方案
flash插件,現(xiàn)在用的很少
代理服務(wù)器,需要服務(wù)器端做額外開(kāi)發(fā)
jsonp,只支持get請(qǐng)求
cors,通過(guò)http頭的Access-Control-Allow-Origin驗(yàn)證
編寫(xiě)jquery插件原則給$.fn綁定函數(shù),實(shí)現(xiàn)插件的代碼邏輯;
插件函數(shù)最后要return this;以支持鏈?zhǔn)秸{(diào)用;
插件函數(shù)要有默認(rèn)值,綁定在$.fn.
用戶(hù)在調(diào)用時(shí)可傳入設(shè)定值以便覆蓋默認(rèn)值。
擴(kuò)展jQuery對(duì)象的功能十分簡(jiǎn)單,但是我們要遵循jQuery的原則,編寫(xiě)的擴(kuò)展方法能支持鏈?zhǔn)秸{(diào)用、具備默認(rèn)值和過(guò)濾特定元素,使得擴(kuò)展方法看上去和jQuery本身的方法沒(méi)有什么區(qū)別。
此篇跳過(guò)了js中的面向?qū)ο螅唠A函數(shù),正則,原型等難點(diǎn),下篇等我好好研究一下繼續(xù)
參考資料 Javascript多維數(shù)組扁平化
廖雪峰老師的js教程
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/80603.html
摘要:巔峰人生年老兵思路上的轉(zhuǎn)變,遠(yuǎn)比單純提升技術(shù)更有價(jià)值本文節(jié)選自趙成教授在極客時(shí)間開(kāi)設(shè)的趙成的運(yùn)維體系管理課,是其對(duì)自己十年技術(shù)生涯的回顧與總結(jié)。趙成教授來(lái)自美麗聯(lián)合集團(tuán),集團(tuán)旗下兩大主力產(chǎn)品是蘑菇街和美麗說(shuō),目前負(fù)責(zé)管理集團(tuán)的技術(shù)服務(wù)團(tuán)隊(duì)。 showImg(https://segmentfault.com/img/remote/1460000012476504?w=1240&h=826...
摘要:應(yīng)該非常小心,避免出現(xiàn)不使用命令直接調(diào)用構(gòu)造函數(shù)的情況。上面代碼表示,使用屬性,確定實(shí)例對(duì)象的構(gòu)造函數(shù)是,而不是。當(dāng)然,從繼承鏈來(lái)看,只有一個(gè)父類(lèi),但是由于在的實(shí)例上,同時(shí)執(zhí)行和的構(gòu)造函數(shù),所以它同時(shí)繼承了這兩個(gè)類(lèi)的方法。 基本概念 類(lèi)和實(shí)例是大多數(shù)面向?qū)ο缶幊陶Z(yǔ)言的基本概念 類(lèi):類(lèi)是對(duì)象的類(lèi)型模板 實(shí)例:實(shí)例是根據(jù)類(lèi)創(chuàng)建的對(duì)象但是,JavaScript語(yǔ)言的對(duì)象體系,不是基于類(lèi)的,...
摘要:原文發(fā)布在數(shù)組應(yīng)該是日常開(kāi)發(fā)中最常見(jiàn)的數(shù)據(jù)結(jié)構(gòu)了,雖然常見(jiàn),但是卻不一定能優(yōu)雅地處理好,中數(shù)組的處理方法很多,各個(gè)方法的參數(shù)返回值是否修改原數(shù)組等也容易記混。 原文發(fā)布在:http://blog.xiaofeixu.cn/2017... 數(shù)組應(yīng)該是日常開(kāi)發(fā)中最常見(jiàn)的數(shù)據(jù)結(jié)構(gòu)了,雖然常見(jiàn),但是卻不一定能優(yōu)雅地處理好,JavaScript中數(shù)組的處理方法很多,各個(gè)方法的參數(shù)、返回值、是否修...
摘要:特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 本以為自己收藏的站點(diǎn)多,可以很快搞定,沒(méi)想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補(bǔ)充。有錯(cuò)誤的地方,還請(qǐng)斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應(yīng)和斧正,會(huì)及時(shí)更新,平時(shí)業(yè)務(wù)工作時(shí)也會(huì)不定期更...
閱讀 988·2021-11-22 09:34
閱讀 2169·2021-11-11 16:54
閱讀 2206·2021-09-27 14:00
閱讀 951·2019-08-30 15:55
閱讀 1537·2019-08-29 12:46
閱讀 611·2019-08-26 18:42
閱讀 649·2019-08-26 13:31
閱讀 3191·2019-08-26 11:52