1.JavaScript把null、undefined、0、NaN和空字符串''視為false,其他值一概視為true,因此上述代碼條件判斷的結(jié)果是true
2.訪問屬性是通過.操作符完成的,但這要求屬性名必須是一個有效的變量名。如果屬性名包含特殊字符,就必須用''括起來,訪問這個屬性也無法使用.操作符,必須用['xxx']來訪問:'middle-school':'No.1 Middle School',xiaohong['middle-school'];//'No.1 Middle School'
3由于JavaScript允許傳入任意個參數(shù)而不影響調(diào)用,因此傳入的參數(shù)比定義的參數(shù)多也沒有問題,雖然函數(shù)內(nèi)部并不需要這些參數(shù):要避免收到undefined,可以對參數(shù)進行檢查
4.JavaScript還有一個免費贈送的關(guān)鍵字arguments,它只在函數(shù)內(nèi)部起作用,并且永遠指向當(dāng)前函數(shù)的調(diào)用者傳入的所有參數(shù)。arguments類似Array但它不是一個Array;
5.為了獲取除了已定義參數(shù)a、b之外的參數(shù),我們不得不用arguments,并且循環(huán)要從索引2開始以便排除前兩個參數(shù),這種寫法很別扭,只是為了獲得額外的rest參數(shù),有沒有更好的方法?ES6標(biāo)準(zhǔn)引入了rest參數(shù),rest參數(shù)只能寫在最后,前面用...標(biāo)識,從運行結(jié)果可知,傳入的參數(shù)先綁定a、b,多余的參數(shù)以數(shù)組形式交給變量rest,所以,不再需要arguments我們就獲取了全部參數(shù)。如果傳入的參數(shù)連正常定義的參數(shù)都沒填滿,也不要緊,rest參數(shù)會接收一個空數(shù)組(注意不是undefined)
6.JavaScript引擎有一個在行末自動添加分號的機制,這可能讓你栽到return語句的一個大坑,正常情況return后同一行緊跟一個“{”
7.JavaScript的函數(shù)定義有個特點,它會先掃描整個函數(shù)體的語句,把所有申明的變量“提升”到函數(shù)頂部:var x = 'Hello, ' + y;只要y在該語句后面聲明,這句并不報錯,但是console.log顯示Hello, undefined,說明變量y的值為undefined。這正是因為JavaScript引擎自動提升了變量y的聲明,但不會提升變量y的賦值,由于JavaScript的這一怪異的“特性”,我們在函數(shù)內(nèi)部定義變量時,請嚴(yán)格遵守“在函數(shù)內(nèi)部首先申明所有變量”這一規(guī)則。最常見的做法是用一個var申明函數(shù)內(nèi)部用到的所有變量
8.不在任何函數(shù)內(nèi)定義的變量就具有全局作用域。實際上,JavaScript默認(rèn)有一個全局對象window,全局作用域的變量實際上被綁定到window的一個屬性,進一步大膽地猜測,我們每次直接調(diào)用的alert()函數(shù)其實也是window的一個變量:這說明JavaScript實際上只有一個全局作用域。任何變量(函數(shù)也視為變量),如果沒有在當(dāng)前函數(shù)作用域中找到,就會繼續(xù)往上查找,最后如果在全局作用域中也沒有找到,則報ReferenceError錯誤
9.全局變量會綁定到window上,不同的JavaScript文件如果使用了相同的全局變量,或者定義了相同名字的頂層函數(shù),都會造成命名沖突,并且很難被發(fā)現(xiàn)。
減少沖突的一個方法是把自己的所有變量和函數(shù)全部綁定到一個全局變量中。例如:// 唯一的全局變量MYAPP:varMYAPP = {};// 其他變量:MYAPP.name ='myapp';MYAPP.version =1.0;// 其他函數(shù):MYAPP.foo =function(){return'foo';};
10.高階函數(shù)除了可以接受函數(shù)作為參數(shù)外,還可以把函數(shù)作為結(jié)果值返回。我們來實現(xiàn)一個對Array的求和。通常情況下,求和的函數(shù)是這樣定義的:
functionsum(arr){returnarr.reduce(function(x, y){returnx + y; });}sum([1,2,3,4,5]);// 15
但是,如果不需要立刻求和,而是在后面的代碼中,根據(jù)需要再計算怎么辦?可以不返回求和的結(jié)果,而是返回求和的函數(shù)!functionlazy_sum(arr){varsum =function(){returnarr.reduce(function(x, y){returnx + y; }); }returnsum;}var f = lazy_sum([1,2,3,4,5]);f();//15
11.閉包,注意到返回的函數(shù)在其定義內(nèi)部引用了局部變量arr,所以,當(dāng)一個函數(shù)返回了一個函數(shù)后,其內(nèi)部的局部變量還被新函數(shù)引用,所以,閉包用起來簡單,實現(xiàn)起來可不容易。另一個需要注意的問題是,返回的函數(shù)并沒有立刻執(zhí)行,而是直到調(diào)用了f()才執(zhí)行。
閉包是攜帶狀態(tài)的函數(shù),返回的函數(shù)沒有立即調(diào)用,所以不能使用可能改變的變量,返回的函數(shù)記錄了外部函數(shù)的參數(shù)和局部變量
12.創(chuàng)建一個匿名函數(shù)并立刻執(zhí)行”的語法:(function(x){returnx * x;})(3);// 9
function* 生成器函數(shù)返回生成器對象,然后通過多次調(diào)用yield返回值,也是記錄狀態(tài)的函數(shù)
13.箭頭函數(shù)和匿名函數(shù)有個明顯的區(qū)別:箭頭函數(shù)內(nèi)部的this是詞法作用域,由上下文確定。我理解的是 正經(jīng)的匿名函數(shù)里,this是誰調(diào)用它 它就指向誰,但在箭頭函數(shù)里,誰調(diào)用它 它不管,它只看this.xx里的xx是在哪聲明的,誰聲明的this就指向誰
14.number、string、boolean、function和undefined有別于其他類型。特別注意null的類型是object,Array的類型也是object,如果我們用typeof將無法區(qū)分出null、Array和通常意義上的object——{}。
15.不要使用new Number()、new Boolean()、new String()創(chuàng)建包裝對象;
用parseInt()或parseFloat()來轉(zhuǎn)換任意類型到number;
用String()來轉(zhuǎn)換任意類型到string,或者直接調(diào)用某個對象的toString()方法;
通常不必把任意類型轉(zhuǎn)換為boolean再判斷,因為可以直接寫if (myVar) {...};
typeof操作符可以判斷出number、boolean、string、function和undefined;
判斷Array要使用Array.isArray(arr);
判斷null請使用myVar === null;
判斷某個全局變量是否存在用typeof window.myVar === 'undefined';
函數(shù)內(nèi)部判斷某個變量是否存在用typeof myVar === 'undefined'。
任何對象都有toString()方法嗎?null和undefined就沒有!確實如此,這兩個特殊值要除外,雖然null還偽裝成了object類型。
? number對象調(diào)用toString()報SyntaxError:123.toString();//SyntaxError遇到這種情況,要特殊處理一下:123..toString();//'123', 注意是兩個點!(123).toString();//'123'
16.NumberObject.toFixed(num)方法返回的是string類型,不能直接拿來運算