1、數組初始化表達式
數組直接量中的清單逗号之間的元素可以省略,這時省略的空位會填充undefined。如:
var arr = [1,,,,,6];
console.log(arr[2]); //列印數組中索引為2的值->undefined
數組直接量的元素清單結尾處可以留下單個逗号,這時并不會建立一個新的值為undefined的元素。
2、運算符
(1)、javascript總是嚴格按照從左至右的順序來計算表達式的。 如:
w = x + y * z;
/*
首先計算表達式w,然後計算x,y,z,然後y的值與z的值相乘,再加上x的值,最後指派給w所指代的變量或屬性。
*/
(2)、所有數字都是浮點型,除法運算的結果也是浮點型。如5/2結果是2.5。 (3)、加号的轉換規則優先考慮字元串的連接配接。(操作數中含有字元串時),但是 “++”或“--”運算符從不進行字元串的連接配接操作。
in運算符 用于檢測某個屬性名是否屬于某個對象。 當屬性名所對應的值初始化為undefined時,檢測結果也為true; 當屬性名被delete後,再次檢測,結果為false。
var point = { //定義一個對象
x: 1,
y: 1
};
console.log("x" in point); //true
console.log("z" in point); //false
console.log("toString" in point); //true:對象繼承了toString()方法
instanceof運算符 用于檢測某個對象是否是某個類的執行個體。所有的對象都是Object的執行個體。
var d = new Date(); //通過Date()構造函數執行個體化一個新的對象
console.log(d instanceof Date); //true
console.log(d instanceof Object); //true
console.log(d instanceof Number); //false
3、邏輯表達式
(1)、 邏輯與(&&) 原理:運算符首先計算左操作數的值,即“&&”左側的表達式。如果計算結果是假值,那麼整個表達式的結果也一定是假值,是以“&&”會傳回左操作數的值,而并不會對右操作數進行計算,将左操作數的值作為整個表達式計算的結果。 反過來,左操作數的值為真值時,會計算右操作數的值,不管是真是假,都會傳回右操作的值作為整個表達式計算的結果。
var o = {
x: 3
};
var p = null;
console.log(o && o.x); //o和o.x都為真,傳回o.x的值3
console.log(p && p.x); //p為假值,傳回p的值null,不去計算p.x
(2)、 邏輯或(||) 原理: 運算符首先計算左操作數的值,即“||”左側的表達式。如果計算結果是真值,那麼整個表達式的結果也一定是真值,是以“||”會傳回左操作數的值,而并不會對右操作數進行計算,将左操作數的值作為整個表達式計算的結果。 反過來,左操作數的值為假值時,會計算右操作數的值,不管是真是假,都會傳回右操作的值作為整個表達式計算的結果。 最常用的方式是從一組備選表達式中選出第一個真值表達式:
//如果max_width已經定義,直接使用它;否則在preferences對象中查找max_width
//如果沒有定義它,則使用一個寫死的常量
var max = max_width || preference.max_width || 500;
(3)、 邏輯非(!) 對操作數的布爾值進行求反。 如:x是真值,則!x傳回false。
// 對于p和q取任意值,這兩個等式都永遠成立
!(p && q) == !p || !q
!(p || q) == !p && !q
4、指派表達式
在大多數情況下,表達式 a op= b (op代表一個運算符) 這個表達式和 a = a op b 是等價的。 特例:下面兩個表達式不等價
var data = [1, 2, 3, 4];
for (var i = 0; i < 4; i++) {
//根據表達式從左到右的運算順序,++運算法則,先計算data[i]的值為1,i再加1
//1*2 = 2,求得第一個值,i++,i為3,再次執行循環
console.log(data[i++] *= 2); //2,6
}
for (var j = 0; j < data.length; j++) {
//同上,先計算=左邊的值後,j+1變為1,然後計算右邊的表達式值,
//此時j為1,data[j]=2,求得第一個值為4,然後j+1變為2,
//j++,j為3,再次執行循環
console.log(data[j++] = data[j++] * 2); //4 NaN
}
5、eval()
隻有一個參數。如果傳入的參數不是字元串,它直接傳回這個參數。 作用:解析并運作由javascript源碼組成的字元串。 如:
eval("3+2") // 5
eval("var y = 3"); //聲明一個新的局部變量y
它使用了調用它的變量作用域環境。直接調用eval()時,它總是在調用它的上下文作用域内執行。其他的間接調用則使用全局對象作為其上下文作用域,并且無法讀、寫、定義局部變量和函數。如:
var geval = eval; //使用别名調用eval将是全局eval
var x = "global",
y = "global";
function f() { //函數内執行的是局部的eval
var x = "local";
eval("x += 'change';"); // 直接eval更改局部變量的值
return x; //傳回更改後的局部變量
}
function g() { //函數内執行的是全局的eval
var y = "local";
geval("y += 'changed';"); //間接調用更改了全局變量的值
return y; //傳回未更改的局部變量
}
console.log(f(), x); // localchange global
console.log(g(), y); // local globalchanged
在嚴格模式下,即es5 。代碼段以 “ use strict ”開始,eval執行的代碼段可以查詢或更改局部變量,但不能在局部作用域中定義新的變量或函數。同時,eval被列為保留字,不能用一個别名覆寫eval()函數,并且變量名、函數名、函數參數或異常捕獲的參數都不能取名為“eval”。
6、delete運算符
delete是一進制操作符,它用來删除對象屬性或數組元素。 如:
var o = { x : 1, y : 2}; //定義一個對象
delete o.x; //删除一個屬性
"x" in o //false 屬性不存在
var a = [1,2,3]; //定義一個數組
delete a[2]; //删除索引為2 的數組元素
2 in a; //false 索引為2的數組元素不存在
a.length // 3, 數組長度并沒有改變,因為其它值的索引并沒有改變
但是,一些内置核心和用戶端屬性是不能被删除的,通過var語句聲明的變量也不能删除,function語句定義的函數和函數參數也不能删除。 在es5嚴格模式下,如果删除的操作數非法,将抛出一個文法錯誤的異常,同時删除不可配置屬性時會抛出類型錯誤異常。在非嚴格模式下,隻是簡單的傳回false,并不會報錯。
var o = { x:1, y:2};
delete o.x; //true
typeof o.x; //undefined 屬性不存在
delete o.x; //true 不存在屬性
delete o; //false var聲明不能删除
delete 1; //true 不是左值(屬性)
this.x = 1; //全局定義一個屬性
delete x; //true(非嚴格模式下) 嚴格模式下使用 delete this.x