JavaScript中五種常見運算符


一. in運算符

  in運算符希望它的左操作數是一個字符串或可以轉換為字符串,希望它的右操作數是一個對象。如果右側的對象擁有一個名為左操作數值的屬性名,那么表達式返回true。例如:

var point = {x:1, y:1};
'x' in point    //=>true:對象有一個名為'x'的屬性
'z' in point    //=>false:對象中不存在名為'z'的屬性
'toString' in point    //=>true:對象繼承了toString()方法

var data = [7, 8, 9];
'0' in data    //=>true:數組包含元素'0'
1 in data      //=>true:數字轉換為字符串
3 in data      //=>false:沒有索引為3的元素

  注意:①當通過in判斷一個字符串是否是一個對象的屬性名時,這個判斷也會包含對該對象繼承屬性的檢測;

二. instanceof運算符  

  instanceof運算符希望左操作數是一個對象,右操作數標識對象的類。如果左側對象是右側類的實例,則表達式返回true,否則返回false。因為JavaScript中對象的類是通過初始化它們的構造函數來定義的,所以instanceof的右操作數應當是一個函數。例如:

var d = new Date();    //通過Date()構造函數來創建一個新對象
d instanceof Date;    //=>true:d是由Date()創建的
d instanceof Object;    //=>true:所有對象都是Object的實例
d instanceof Number;    //=>false:計算結果為false,d不是一個Number對象

var a = [1, 2, 3];
a instanceof Array;    //=>true:a是一個數組
a instanceof Object;    //=>true:所有數組都是對象
a instanceof RegExp;    //=>false:數組不是正則表達式

var b = 3;
b instanceof Number;    //=>false:右操作數不是一個對象,只是一個原始值(切記這里不做類型轉換:當右操作數是合法的函數時,只要右操作數是任何原始類型都會返回false)

  注意:①所有對象都是Object的實例;②通過instanceof判斷一個對象是否是一個類的實例的時候,這個判斷也會包含對“父類”的檢測;③如果instanceof的左操作數不是對象的話,instanceof返回false,如果右操作數不是函數,則拋出一個類型錯誤異常(先檢測右操作數是否合法,再檢測左操作數,最后判斷表達式)。

三. typeof運算符

  typeof是一元運算符,放在其單個操作數的前面,操作數可以是任意類型。返回值為表示操作數類型的一個字符串。下面是任意值在typeof運算后的返回值: 

x typeof x
undefined "undefined"
null "object"
true或false "boolean"
任意數字或NaN "number"
任意字符串 "string"
任意函數 "function"
任意內置對象(非函數) "object"
任意宿主對象 有編譯器各自實現的字符串,但不是"undefined"、"boolean"、"number"或"string"

  typeof運算符可以帶上圓括號,這讓typeof看起來像一個函數名,而不是一個運算符:typeof(i)

  新增:關於instanceof和typeof,下面記述一個例子:

四. delete運算符

  delete是一元操作符,它用來刪除對象屬性或者數組元素,當然它也有返回值。例如:

var o = {x:1, y:2};
delete o.x;      //=>true:成功刪除一個屬性
'x' in o;    //=>false:這個屬性在對象中不再存在了
'y' in o;    //=>true
o.x;    //=>undefined:讀取不存在的屬性將返回undefined  
delete o.x;    //=>true:刪除不存在的屬性,返回true
delete o.z;    //=>true:刪除不存在的屬性,返回true

var a = [1, 2, 3];
2 in a;    //=>true:元素2在數組中
delete a[2];    //=>true:成功刪除一個數組元素
2 in a;    //=>false:元素2已經不在數組中了
a.length;    //=>3:注意,數組長度並沒有改變
delete a[3];    //=>true:刪除不存在的元素,返回true
a[2];    //=>undefined:讀取不存在的元素將返回undefined

var b = [1, 2, undefined];
2 in b;    //=>true:元素2在數組b中
b[2];    //=>undefined:讀取元素2的值,返回其值undefined
delete b[2];    //=>true:成功刪除一個數組元素
2 in b;    //=>false:元素2已經不再數組中了
b.length;    //=>3:數組長度未變
b[2];    //=>undefined:讀取不存在的元素返回undefined 

可以看到:delete如果刪除成功或者刪除不存在的屬性或元素時都會返回true,那么什么時候返回false呢?其實,並不是所有屬性都可刪除,一些內置核心和客戶端屬性是不能刪除,用戶通過var語句聲明的變量不能刪除(當用var聲明全局變量時,這個變量也是全局對象window的一個屬性),同樣,通過function語句定義的函數和函數參數也不能刪除。例如:

var o = {x:1, y:2};
var aa = 22;
delete o.x;    //=>true
typeof o.x;    //=>undefined
delete o;    //=>false:不能刪除通過var聲明的變量,返回false
delete aa;    //=>false:不能刪除通過var聲明的變量,返回false
delete window.aa;    //=>false:無法刪除
delete this.aa;    //=>false:無法刪除
function myTest(con){
    console.log(delete con);    //=>false:不能刪除函數參數
    console.log('myTest:' + con);
}
delete myTest;//=>false:不能刪除通過function語句定義的函數

注意:在ECMAScript 5嚴格模式中,如果delete的操作數是非法的,比如變量、函數或函數參數,delete操作將拋出一個語法錯誤(Syntax Error)異常,只有操作數是一個屬性訪問表達式的時候它才會正常工作。在嚴格模式下,delete刪除不可配置的屬性時會拋出一個類型錯誤異常。在非嚴格模式下,這些delete操作都不會報錯,只會簡單地返回false,以表明操作數不能執行刪除操作。當使用var聲明一個變量時,創建的這個屬性就是不可配置的,所以上面各種刪除變量aa都返回false,表示無法刪除,當然我們這里討論的就是非嚴格模式嘛。在非嚴格模式中,如果給一個沒有使用var聲明的變量賦值的話,JavaScript會自動創建一個隱式的全局變量,以這種方式創建的變量是全局對象的正常的可配置屬性,所以可以刪除它們,Chrome運行結果也正是這樣:

更要注意的一點是:在使用任務鏈進行部分var聲明時,也會創建隱式全局變量,例如:

下面的例子更是驗證了這個:

要想避免這種隱式全局變量,就要這樣寫:

var aa=0,bb=0;
delete aa;//=>false
delete bb;//=>false

還有一點就是:delete希望它的操作數是一個左值,如果它不是左值,那么delete將不進行任何操作同時返回true。例如:

delete 1;    //數字1不是一個左值,返回true

五. void運算符

  void是一元運算符,它出現在操作數之前,操作數可以是任意類型,操作數會照常計算,但永遠返回undefined。例如:

var aa = 33;
var bb = 44;
var cc = 0;
var dd = void(aa+bb);    //dd=undefined
var ee = void(cc = aa+bb);    //ee=undefined,cc=77
//注意:最后一句不能寫成var ee = void(cc = aa + bb;);,因為void一元運算符,后面是操作數,不能是完整的語句    

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM