JavaScript小細節點羅列

衆所周知,JavaScript爲屬性的訪問定義了兩種語法方式:

複製代碼

表達式.標識符 // 表達式(指定對象)    標識符(指定需要訪問的屬性的名稱)
表達式1(指定對象)  

var O = {a:1,b:{c:3}}
var A = [O,4,[5,6,7]]

O.a //1
O.b.c //3
O["a"] //1
A[1] //4
A[0].b.c //3
A[2]["2"] //7

複製代碼

第一種方法我們使用點"."來進行屬性的訪問,第二種則是使用方括號來進行屬性訪問。其實如上我們就可以輕鬆發現兩種方法的區別,第二種方法的方括號內也是一個表達式。

但是這兩種方法的第一個表達式都是先進行計算的,如果計算結果是空或者未定義那麼就會拋出錯誤,如果運算結果不是對象或者數組,JS會將其轉化爲對象(例如下面代碼塊的字符串)。

var str = "Hello World!";var world = s.substring(s.indexOf(" ")+1, s.length)

如果運算結果不是對象或者數組,JS會將其轉化爲對象=》有些人會奇怪,字符串不是對象,爲什麼它還具有屬性?這是因爲我們在進行屬性訪問的時候,JS就會將字符串調用 new String(str) 來轉換成對象,而提供這個方法新創建的對象自然就繼承(關於對象的繼承可以查閱相關資料)了字符串的方法並且用來處理屬性的引用。一旦屬性引用結束了,這個新創建的對象就會被銷燬。當然我這裏只寫了字符串的一個demo,數字布爾值也類似通過Number(),Boolean()構造函數來進行對象創建。

回到屬性訪問表達式,如果表達式後跟隨"."和標識符,就會查找這個標識符所指定的屬性的值沒並將其作爲整個表達式返回的值。如果對象表達式跟隨一堆方括號,則會計算方括號內的表達式的值並將其轉化爲字符串,當然這兩方法種如果訪問的屬性是不存在的。會返回undefine。

我們可以看出,使用"."+標識符的寫法更加簡單,並且我們有時候習慣了鏈式調用的時候更加喜歡".",但是,需要注意的是,這種方式下,我們要訪問的屬性名必須是合法的。如果我們進行訪問的屬性名稱是一個保留字,或者包含空格,或者是一個數字,或者是通過表達式計算得出的值,這時候的屬性訪問必須要使用方括號。

delete運算符

delete是一元運算符,我們可以使用它來刪除對象屬性或者數組元素。

delete希望他的操作數是一個左值,如果我們誤用使得他的操作數不是一個左值,那麼delete就不會進行任何操作並且返回true,當然並不是所有屬性都是能夠刪除的,用戶var聲明的變量,自定義函數,函數參數,內置核心屬性等是不能給刪除的,刪除非法會拋出錯誤。

這裏插入補充下左值:所謂左值,簡單點說就是可以被賦值的表達式,在ES規範中是用內部類型引用(Reference)描述的,其作用爲存放數據空間,且存放是允許的。比如這裏的屬性訪問表達式。

雖然delete運算符可以刪除對象的屬性,但是我們要知道,delete其實只是斷開了屬性和宿主對象的聯繫,而不會操作屬性中的屬性。而且delete運算符只能刪除自有屬性,不能刪除繼承屬性。

a = { b:{c:1} };
d = a.b;delete a.b;
console.log(d.c) //結果仍舊是1,可以看出delete其實只是斷開可屬性和宿主對象的聯繫並沒有將其銷燬

複製代碼

o = {a:1};delete o.a; //刪除屬性a並返回truedelete o.x; //因爲a屬性不存在,什麼都不做並返回truedelete o.toString; //因爲toString是繼承來的,什麼都不做並返回truedelete 110; //沒有意義,返回truedelete Object.prototype; //返回falsevar b = 1;delete this.b; //返回falsefunction f(){};delete this.f; //返回false

複製代碼

 邏輯運算符

運算符示例說明
邏輯與 (&&)expr1&&expr2如果expr1 能轉換成false則返回expr1,否則返回expr2. 因此, 在Boolean環境中使用時, 兩個操作結果都爲true時返回true,否則返回false.
邏輯或 (||)expr1||expr2如果expr1能轉換成true則返回expr1,否則返回expr2. 因此,在boolean環境(在if的條件判斷中)中使用時, 二者操作結果中只要有一個爲true,返回true;二者操作結果都爲false時返回false.
邏輯非(!)!expr如果單個表達式能轉換爲true的話返回false,否則返回true.

在JS計算邏輯中我們在使用邏輯運算符會有一個短路原理。如下

複製代碼


var e = a && 1; //1
var f = b && 1; //false

複製代碼

上面代碼塊的變量c賦值時,a和1都是真,但是因爲js的短路原理,在邏輯或中只要排在前面的a爲真,那麼後面的1就會直接忽略,排在前面的操作數爲假纔會計算到後面的操作數。同理在使用邏輯與時,只要排在前面的操作數是爲假,那麼js就會直接忽略後面的操作數而讓運算結果直接爲false,如果前面的操作數爲真,就會繼續計算後面的操作數,最後如果後面操作數爲真,賦值的纔是後面的操作數。

var a = 真1 || 真2 //真1var b = 假 || 真3 //真3var c = 真4 && 真5 //真5var d = 假 && 真6 //假


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章