1、JavaScript允許對任意數(shù)據(jù)類型做比較
第一種是==比較,它會自動轉換數(shù)據(jù)類型再比較,很多時候,會得到非常詭異的結果;
第二種是===比較,它不會自動轉換數(shù)據(jù)類型,如果數(shù)據(jù)類型不一致,返回false,如果一致,再比較。
由于JavaScript這個設計缺陷,不要使用==比較,始終堅持使用===比較。
浮點數(shù)在運算過程中會產生誤差,因為計算機無法精確表示無限循環(huán)小數(shù)。要比較兩個浮點數(shù)是否相等,只能計算它們之差的絕對值,看是否小于某個閾值:
Math.abs(1/3- (1-2/3)) <0.0000001;//true
2、JavaScript的設計者希望用null表示一個空的值,而undefined表示值未定義。事實證明,這并沒有什么卵用,區(qū)分兩者的意義不大。大多數(shù)情況下,我們都應該用null。undefined僅僅在判斷函數(shù)參數(shù)是否傳遞的情況下有用。
3、數(shù)組Array
3.1、直接給Array的length賦一個新的值會導致Array大小的變化,即數(shù)組的length屬性是可寫的
如果賦一個比length大的值,數(shù)組多出的部分用undefined代替
如果通過索引賦值時,索引超過了范圍,同樣會引起Array大小的變化:
var arr = [1,2,3];
arr[5] ='x';
arr;// arr變?yōu)閇1, 2, 3, undefined, undefined, 'x']
如果賦一個比length小的值,那么多出的部分就會被截斷。(引申:如果賦0,則是清空數(shù)組)
但是需要注意一點,通過點屬性的方式及 "att.屬性 " 來添加內容是不會引起length長度的變化,即js中的length只用來描述索引元素的長度,忽略關聯(lián)元素
3.2、對于Array,如果不給slice()傳遞任何參數(shù),它就會從頭到尾截取所有元素。利用這一點,我們可以很容易地淺復制一個Array:
var arr = ['A','B','C','D','E','F','G'];
var aCopy = arr.slice();
aCopy;// ['A', 'B', 'C', 'D', 'E', 'F', 'G']
aCopy === arr;// false
3.3、對于數(shù)組的concat()方法,習慣上我們認為它接收一個數(shù)組參數(shù),其實它可以接收任意個非數(shù)組元素和Array(如果是個一維數(shù)組,則會進行一次拆分,否則不拆分),然后全部添加到新的Array里:
var arr = ['A','B','C'];
arr.concat(1,2, [3,4]);// ['A', 'B', 'C', 1, 2, 3, 4]
注意:concat對添加的數(shù)組只進行一次拆分,如果接收的Array是個多維數(shù)組,不會進行拆分
3.4、Array的sort()方法默認把所有元素先轉換為String再排序,如果不知道sort()方法的默認排序規(guī)則,直接對數(shù)字排序,絕對栽進坑里!
4、對象
對象的屬性訪問可以通過兩個方式進行:一種是"對象.屬性名",一種是 對象[ '屬性名' ]
如果屬性名是個合常規(guī)的,上邊兩種方式都可以,但是如果屬性名中含有特殊的字符,如“-” 或者 空格 ,則只能通過第二種方式進行訪問
測試一個對象是否擁有某一屬性,可以用in操作符 或者 hasOwnProperty()方法,in會搜索原型鏈,檢索對象自己的和繼承過來的屬性,而hasOwnProperty()方法只會檢測是否是自己的屬性
5、for( item ?in target)
如果target是一個對象,則item代表的是對象的屬性
如果target是一個數(shù)組,由于Array也是對象,而它的每個元素的索引被視為對象的屬性的一部分,所以item代表的是索引,但是如果不通過Array提供的方法(方法和初始化)向數(shù)組中添加元素,你在數(shù)組上手動添加的屬性不會被認為是索引的,即length是不會發(fā)生變化的,但是遍歷的時候屬性包括了索引和添加上來的內容,如下
var a = ['A','B','C'];
a.name ='Hello';
for(var x in a) {
? ? alert(x);// '0', '1', '2', 'name'
}
a // ['A','B','C']
a.length // 3
6、方法內部有關變量的提升
JavaScript的函數(shù)定義有個特點,它會先掃描整個函數(shù)體的語句,把所有申明的變量“提升”到函數(shù)頂部,只是提升聲明,賦值操作是在代碼執(zhí)行到對應位置的時候才執(zhí)行
functionfoo(){
? ? var x ='Hello, '+ y;
? ? alert(x);
? ? var y ='Bob';
}
等價于:
functionfoo(){
? ? var y;// 提升變量y的申明
? ? var x ='Hello, '+ y;? ?
? ? alert(x);
? ? y ='Bob';
}
所以在開發(fā)中,應嚴格遵守“在函數(shù)內部首先申明所有變量”這一規(guī)則
7、作用域
Javascript的變量范圍是以函數(shù)為基礎的,每個函數(shù)都有它自己的變量范圍,Javascript這一點上表現(xiàn)的很酷,根本不理睬一些無意義的花括弧包起來的范圍。
不在任何函數(shù)內定義的變量就具有全局作用域
var a = 1 等價于 window.a = 1
如果對象中定義了方法,要保證方法中this指向正確,必須用obj.xxx()的形式調用,否則this會被調用方法時調用該方法的對象改寫
方法.apply(obj, [ ])、方法.call(obj, arg1, arg2, ...)可以動態(tài)改變方法中的this指向,對于普通方法的調用,我們可以使用 方法.apply(null, [ ])和 方法.call(null,arg1,arg2,...)的方式,比如調用Math.max(3, 5, 4),分別用apply()和call()實現(xiàn)如下:
Math.max.apply(null, [3,5,4]);// 5
Math.max.call(null,3,5,4);// 5
8、閉包
返回閉包時牢記的一點就是:返回函數(shù)不要引用任何循環(huán)變量,或者后續(xù)會發(fā)生變化的變量。
如果一定要引用循環(huán)變量怎么辦?方法是再創(chuàng)建一個函數(shù),用該函數(shù)的參數(shù)綁定循環(huán)變量當前的值(即函數(shù)有一個參數(shù)來接收變量)并用“創(chuàng)建一個匿名函數(shù)并立刻執(zhí)行”的語法將i的值傳入,無論該循環(huán)變量后續(xù)如何更改,已綁定到函數(shù)參數(shù)的值不變。
閉包的實質:閉包就是攜帶狀態(tài)的函數(shù)!是攜帶狀態(tài)的函數(shù)!是攜帶狀態(tài)的函數(shù)!并且它的狀態(tài)可以完全對外隱藏起來。!
9、包裝對象
包裝對象用new創(chuàng)建:
var n =new Number(123);// 123,生成了新的包裝類型
var b =new Boolean(true);// true,生成了新的包裝類型
var s =new String('str');// 'str',生成了新的包裝類型
雖然包裝對象看上去和原來的值一模一樣,顯示出來也是一模一樣,但他們的類型已經(jīng)變?yōu)閛bject了!所以,包裝對象和原始值用===比較會返回false!
所以閑的蛋疼也不要使用包裝對象!尤其是針對string類型?。?!
如果我們在使用Number、Boolean和String時,沒有寫new,那么Number()、Boolean()和String()被當做普通函數(shù),把任何類型的數(shù)據(jù)轉換為number、boolean和string類型(注意不是其包裝類型)
所以閑的蛋疼也不要使用包裝對象!尤其是針對string類型!??!
10、字符串型數(shù)值快速轉變?yōu)閿?shù)值類型,只需在字符串前邊加上“+”
var a = '123.4' ;
var b = +a + 100 // b=223.4
11、數(shù)值快速取整:數(shù)值|0
總結一下,有這么幾條規(guī)則需要遵守:
不要使用new Number()、new Boolean()、new String()創(chuàng)建包裝對象;
用parseInt()或parseFloat()來轉換任意類型到number;
用String()來轉換任意類型到string,或者直接調用某個對象的toString()方法;
通常不必把任意類型轉換為boolean再判斷,因為可以直接寫if (myVar) {...};
typeof操作符可以判斷出number、boolean、string、function和undefined;
判斷Array要使用Array.isArray(arr);
判斷null請使用myVar === null;
判斷某個全局變量是否存在用typeof window.myVar === 'undefined';
函數(shù)內部判斷某個變量是否存在用typeof myVar === 'undefined'。
12、
event.currentTarget指向事件所綁定的元素,
而event.target始終指向事件發(fā)生時的元素。