JS中六種數據類型(3)——Number、string、Object


Number類型應該是ECMAScript中最令人關注的數據類型了,這種類型使用IEEE754格式來表示整數和浮點數值(浮點數值在某些語言中也被稱為雙精度數值)。為支持各種數值類型,ECMA-262定義了不同的數值字面量。

    最基本的數值字面量格式是十進制整數,十進制整數可以像下面這樣直接在代碼中輸入:

 

    var  item =55;   //整數

 

    除了以十進制表示外,整數還可以通過八進制(以8為基數)或十六進制(以16為基數)的字面值來表示。其中,八進制字面值的第一位必須是零(0),然后是八進制數字序列(0-7)。如果字面值中的數值超出了范圍,那么前導零將被忽略,后面的數值將被當做十進制數值解析。請看下面的例子:

 

    var color1=070;   //八進制的56

    var color2=079;   //無效的八進制數值——解析為79

    var color3=08;    //無效的八進制數值——解析為8

 

    八進制字面量在嚴格模式下是無效的,會導致支持該模式的JavaScript引擎拋出錯誤。

    十六進制字面值的前兩位必須是0x,后跟任何十六進制數字(0-9及A-F)。其中,字面A-F可以大寫,也可以小寫。如下面的例子所示:

 

    var num1=0xA;    //十六進制的10

    var num2=0x1f;    //十六進制的31

 

    在進行算術計算時,所有以八進制和十六進制表示的數值最終都將被轉換成十進制數值。

    1.浮點數值

    所謂浮點數值,就是該數值中必須包含一個小數點,並且小數點后面必須至少有一位數字。雖然小數點前面可以沒有整數,但我們不推薦這種寫法。一下是浮點數值的幾個例子:

 

    var floatNum1=1.1;

    var floatNum2=0.1;

    var floatNum3=.1;  //有效,但不推薦

 

    由於保存浮點數值需要的內存空間是保存數值的兩倍,因此ECMAScript會不失時機地將浮點數值轉換為整數值。顯然,如果小數點后面沒有跟任何數字,那么這個數值就可以作為整數值來保存。同樣地,如果浮點數值本身表示的就是一個整數(如1.0),那么該值也會被轉換為整數,如下面的例子所示:

 

    var floatNum1=1.;  //小數點后面沒有數字——解析為1

    var floatNum2=10.0;    //整數——解析為10 

  

    對於那些極大或極小的數值,可以用e表示法(即科學計數法)表示的浮點數值表示。用e表示法表示的數值等於e前面的數值乘以10的指數次冪。ECMAScript中e表示法的格式也是如此,即前面是一個數值(可以是整數也可以是浮點數),中間是一個大寫或小寫的字面E,后面是10的冪中的指數,該冪值將用來與前面的數相乘。下面是一個使用e表示法表示數值的例子:

 

    var floatNum=3.125e7 ;   //等於31250000

 

    這個例子中,使用e表示法表示的變量floatNum的形式雖然簡潔,但它的實際值則是31250000.在此,e表示法的實際含義就是“3.125乘以10的七次方”。

    也可以使用e表示法表示極小的數值,如0.00000000000000003,這個數值可以使用更簡潔的3e-17表示。在默認情況下,ECMAScript會將那些小數點后面帶有6個零以上的浮點數值轉換為以e表示法表示的數值(例如,0.0000003會被轉換成3e-7)。

    浮點數值的最高精度是17位小數,但在進行算術計算時其精確度遠遠不如整數。例如,0.1+0.2的結果不是0.3,而是0.300000000000000004。這個小小的舍入誤差會導致無法測定特定的浮點數值。例如:

 

    if(a+b == 0.3){          //不要做這樣的測試

       alert("You got 0.3.");

    }

 

     在這個例子中,我們測試的是兩個數的和是不是等於0.3。如果這兩個數是0.05和0.25,或者是0.15和0.15都不會有問題。而如前所述,如果這兩個數是0.1和0.2,那么測試將無法通過。因此,永遠不要測試某個特定的浮點數值。

    2.數值范圍

    由於內存的限制,ECMAScript並不能保存世界上所有的數值。ECMAScript能夠表示的最小數值保存在Number.MIN_VALUE中——在大多數瀏覽器中,這個值是5e-324;能夠表示的最大數值保存在Number.MAX_VLAUE中——在大多數瀏覽器中,這個值是1.7976931348623157e+328。如果某次計算結果得到了一個超出JavaScript數值范圍的值,那么這個數值將被自動轉換成特殊的Infinity值。具體來說,如果這個數值是負數,則會被轉換成-Infinity(負無窮),如果這個數值是正數,則會被轉換成Infinity(正無窮)。

    如上所述,如果某次計算返回了正或負的Infinity值,那么該值將無法繼續參與下一次的計算,因為Infinity不是能夠參與計算的數值。要想確定一個數值是不是有窮的(換句話說,是不是位於最小和最大的數值之間),可以使用isFinite()函數。這個函數在參數位於最小與最大數值之間時會返回true,如下面的例子所示:

 

    var result=Number.MAX_VALUE + Number.MAX_VALUE;

    alert(isFinite(result)); //false

 

    盡管在計算中很少出現某些值超出表示范圍的情況,但在執行極小或極大數值的計算時,檢測監控這些值是可能的,也是必須的。

    3.NaN

    NaN,即非數值(Not a Number)是一個特殊的數值,這個數值用於表示一個本來返回數值的操作數未返回數值的情況(這樣就不會拋出錯誤了)。例如,在其他編程語言中,任何數值除以0都會導致錯誤,從而停止代碼執行。但在ECMAScript中,任何數值除以0會返回NaN,因此不會影響其他代碼的執行。

    NaN本身有兩個非同尋常的特點。首先,任何涉及NaN的操作(例如NaN/10)都會返回NaN,這個特點在多部計算中有可能導致問題。其次,NaN與任何值都不相等,包括NaN本身。例如,下面的代碼會返回false:

 

    alert(NaN == NaN);//false

 

    針對NaN的這兩個特點,ECMAScript定義了isNaN()函數。這個函數接受一個參數,該參數可以是任何類型,而函數會幫我們確定這個參數是否“不是數值”。isNaN()在接收到一個值之后,會嘗試將這個值轉換為數值。某些不是數值的值會直接轉換為數值,例如字符串“10”或“Boolean”值。而任何不能轉換為數值的值都會導致這個函數返回true。請看下面的例子:

 

     alert(isNaN(NaN)) ; //true

     alert(isNaN(10));   //false(10是一個數值)

    alert(isNaN(“10”));  //false(可以被轉換成數值10)

    alert(isNaN(“blue”));  //true(不能轉換成數值)

    alert(isNaN(true));  //false (可以被轉換成數值1)

 

    這個例子測試了5個不同的值。測試的第一個值是NaN本身,結果當然會返回true。然后分別測試了數值10和字符串“10”,結果這個兩個測試都返回了false,因為前者本身就是數值,而后者可以被轉換成數值。但是字符串“blue”不能被轉換成數值,因此函數返回了true。由於Boolean值true可以轉換成數值1,因此函數返回false。

    4.數值轉換

    有3個函數可以把非數值轉換為數值:Number()、parseInt()和parseFloat()。第一個函數,即轉型函數Number()可以用於任何數據類型,而另兩個函數則專門用於把字符串轉換成數值。這3哥函數對於同樣的輸入會有返回不同的結果。

    Number()函數的轉換規則如下。

  1. 如果是Boolean值,true和false將分別被轉換成1和0.

  2. 如果是數字值,只是簡單的傳入和返回。

  3. 如果是null值,返回0。

  4. 如果是undefined,返回NaN。

  5. 如果是字符串,遵循下列規則:

     a.如果字符串中只包含數字(包括前面帶正號或負號的情況),則將其轉換為十進制數值,即“1”會變成1,“123”會變成123,而“011”會變成11(注意:前導的零被忽略了)   

     b.如果字符串中包含有效的浮點格式,如“1.1”,則將其轉換為對應的浮點數值(同樣,也會忽略前導零);

     c.如果字符串中包含有效的十六進制格式,例如:“0xf”,則將其轉換為相同大小的十進制整數數值;

     d.如果字符串是空的(不包含任何字符),則將其轉換為0;

     e.如果字符串中包含除上述格式之外的字符,則將其轉換為NaN。

   6.如果是對象,則調用對象的valueOf()方法,然后依照前面的規則轉換返回的值。如果轉換的結果是NaN,則調用對象的toString()方法,然后再次依照前面的規則轉換返回的字符串值。

    根據這么多的規則使用Number()把各種數據類型轉換為數值確實有點復雜。下面還是給出幾個具體的例子吧。

 

    var num1=Number("Hello world!");  //NaN

    var num2=Number("");              //0

    var num3=Number("000011");        //11

    var num4=Number(true);            //1

 

    首先,字符串"Hello World!"會被轉換為NaN,因為其中不包含任何有意義的數字值。空字符串會被轉換為0.字符串“000011”會被轉換為11,因為忽略了其前導的零。最后,true值被轉換為1。

    由於Number()函數在轉換字符串時比較復雜而且不夠合理,因此在處理整數的時候更常用的是parseInt()函數。parseInt()函數在轉換字符串時,更多的是看其是否符合數值模式。它會忽略字符串前面的空格,直至找到第一個非空格字符。如果第一個字符不是數字字符或者負號,parseInt()就會返回NaN;也就是說,用parseInt()轉換空字符串會返回NaN(Number()對空字符串返回0)。如果第一個字符是數字字符,parseInt()會繼續解析第二個字符,直到解析完所有后續字符或者遇到了一個非數字字符。例如,"123blue"會被轉換為1234,因為"blue"會被完全忽略。類似地,"22.5"會被轉換為22,因為小數點並不是有效的數字字符。

    如果字符串中的第一個字符是數字字符,parseInt()也能夠識別出各種整數格式(即前面討論的十進制、八進制和十六進制)。也就是說,如果字符串以"0x"開頭且后跟數字字符,就會將其當做一個十六進制整數;如果字符串以"0"開頭且后跟數字字符,則會將其當做一個八進制數來解析。

    為了更好地理解parseInt()函數的轉換規則,下面給出一些例子:

 

    var num1=parseInt("1234blue");   //1234

    var num1=parseInt("");   //NaN

    var num1=parseInt("0xA");   //10(十六進制數)

    var num1=parseInt("22.5");   //22

    var num1=parseInt("070");   //56(八進制數)

    var num1=parseInt("70");   //70(十進制數)

    var num1=parseInt("0xf");   //15(十六進制數)

 

    在使用parseInt()解析像八進制字面量的字符串時,ECMAScript3和5存在分歧。例如:

 

    //ECMAScript 3 認為是56(八進制),ECMAScript 5認為是70(十進制)

    var num=parseInt("070");

 

    在ECMAScript 3 JavaScript引擎中,"070"被當成八進制字面量,因此轉換后的值是十進制的56.而在ECMAScript 5 JavaScript引擎中,parseInt()已經不具有解析八進制值的能力,因此前導的零會被認為無效,從而將這個值當成"70",結果就得到十進制的70。在ECMAScript 5 中,即使是在非嚴格模式下也會如此。

    為了消除在使用parseInt()函數時可能導致的上述困惑,可以為這個函數第二個參數:轉換時使用的技術(即多少進制)。如果知道要解析的值是十六進制格式的字符串,那么指定基數16作為第二個參數,可以保證得到正確的結果,例如:

 

    var num=parseInt("0xAF",16);     //175

 

    實際上,如果指定了16作為第二個參數,字符串可以不帶前面的"0x"如下所示:

 

    var num1=parseInt("AF",16); //175

    var num2=parseInt("AF");    //NaN

 

    這個例子中的第一個轉換成功了,而第二個則失敗了。差別在於第一個轉換傳入了基數,明確告訴parseInt()要解析一個十六進制格式的字符串;要第二個轉換發現第一個字符不是數字字符,因此就自動終止了。

 

    var num1=parseInt("10",2);    //2 (按二進制解析)

    var num2=parseInt("10",8);    //8 (按八進制解析)

    var num3=parseInt("10",10);    //10 (按十進制解析)

    var num4=parseInt("10",16);    //16 (按十六進制解析)

 

    不指定基數意味着讓parseInt()決定如何解析輸入的字符串,因此為了避免錯誤的解析,我們建議無論在什么情況下都明確指定基數。

    與parseInt()函數類似,parseFloat()也是從第一個字符(位置0)開始解析每個字符。而且也是一直解析到字符串末尾,或者解析到遇見一個無效的浮點數字字符為止。也就是說,字符串中的每一個小數點是有效的,而第二個小數點就是無效的了,因此它后面的字符串將被忽略。舉例來說,"22.34.5"將會被轉換為22.34。

    除了第一個小數點有效之外,parseFloat()與parseInt()的第二個區別在於它始終都會忽略前導的零。parseInt()可以識別前面討論過的所有浮點數值格式,也包括十進制整數格式。但十六進制格式的字符串則始終被轉換成0。由於parseFloat()只解析十進制值,因此它沒有用第二個參數指定基數的用法。最后還要注意一點:如果字符串包含的是一個可解析為整數的數(沒有小數點,或者小數點后都是零),parseFloat()會返回整數。以下是使用parseFloat()轉換數值的幾個典型示例。

 

    var num1  =  parseFloat("1234blue");   //1234(整數)

    var num2  =  parseFloat("0xA");   //0

    var num3  =  parseFloat("22.5");   //22.5

    var num4  =  parseFloat("22.34.5");   //22.34

    var num5  =  parseFloat("0908.5);   //908.5

    var num6  =  parseFloat("3.125e7");   //3125000

 

 

 

 

 

 

 

 

 

 

  String類型用於表示由零或多個16位Unicode字符組成的字符序列,即字符串。字符串可以由雙引號(“)或單引號(‘)表示,因此下面兩種字符串的寫法都是有效的:

 

 

var firstName="Marry";

 

var firstName='Jane';

 

 

 

    與PHP中的雙引號和單引號會影響對字符串的解釋方式不同,ECMAScript中的這兩種語法形式沒有什么區別。用雙引號表示的字符串和用單引號表示的字符串完全相同。不過,以引號開頭的字符串也必須以雙引號結尾,而以單引號開頭的字符串必須以單引號結尾。例如,下面這種字符串表示法會導致語法錯誤:

 

//語法錯誤(左右引號必須匹配)

 

var firstName="Nicholas';

 

 

 

    1、字符字面量

 

    String 數據類型包含一些特殊的字符字面量,也叫轉義序列,用於表示非打印字符,或者具有其他用途的字符。這些字符字面量如下表所示:

 

 

 


   
 
這些字符字面量可以出現在字符串中的任意位置,而且也將被作為一個字符來解析,如下面的例子所示:

 

 

 

var text="sigma: \u03a3.";

 

 

 

    這個例子中的變量text有28個字符,其中6個字符長的轉移序列表示1個字符。任何字符串的長度都可以通過訪問其length屬性取得,例如:

 

 

 

alert(text.length);//輸出28

 

 

 

    這個屬性返回的字符數包括16位字符的數目。如果字符串包含雙字節字符,那么length屬性可能不會精確的返回字符串中字符數目。

 

 

 

    2.字符串的特點

 

    ECMAScript中的字符串是不可改變的,也就是說,字符串一旦創建,它們的值就不能改變。要改變某個變量保存的字符串,首先要銷毀原來的字符串,然后再用另一個包含新值的字符串填充該變量,例如:

 

 

 

var  lang="Java";

 

lang=lang+"Script";

 

 

 

    以上示例中的變量lang開始時包含字符串“Java”。而第二行代碼把lang的值重新定義為“Java”與“Script”的組合,即“JavaScript”。實現這個操作的過程如下:首先創建一個能容納10個字符的新字符串,然后再這個字符串中填充"Java"和“Script”,最后一步是銷毀原來的字符串“Java”和字符串“Script”,因為這兩個字符串已經沒用了。這個過程是在后台發生的,而這也是在某些舊版本的瀏覽器(如版本低於1.0的Firefox,IE6等)中拼接字符串時速度很慢的原因所在。但這些瀏覽器后來的版本已經解決了這個低效率的問題。

 

    3.轉換為字符串

 

    要把一個值轉換為一個字符串有兩種方式。第一種是使用幾乎每個值都有的toString()方法。這個方法唯一要做的就是返回相應值的字符串表現。來看下面的例子:

 

 

 

var age=11;

 

//字符串“11”

 

var ageAsString=age.toString(); 

 

var fount=true;

 

//字符串"true"

 

var foundAsString=found.toString()

 

 

 

    數值,布爾值,對象和字符串值(沒錯,每個字符串也都有一個toString()方法,該方法返回值返回串的一個副本)都有toString()方法。但null和undefined值沒有這個方法。

 

    多數情況下,調用toString方法不必傳遞參數。但是,在調用數值的toString()方法時,可以傳遞一個參數:輸出數值的基數。默認情況下,toString()方法以十進制格式返回數值的字符串表示。而通過傳遞基數,toString()輸出以二進制、八進制、十六進制,乃至其他任意有效進制格式表示的字符串值。下面給出幾個例子:

 

 

 

var num=10;

 

alert(num.toString()); //"10"

 

alert(num.toString(2)); //"1010"

 

alert(num.toString(8)); //"12"

 

alert(num.toString(10)); //"10"

 

alert(num.toString(16)); //"a"

 

 

 

    通過這個例子可以看出,通過指定基數,toString()方法會改變輸出的值。而數值10根據基數的不同,可以在輸出時被轉換為不同的數值格式。注意,默認的(沒有參數的)輸出值與指定基數10時的輸出值相同。

 

    在不知道要轉換的值是不是null或undefined的情況下,還可以使用轉型函數String(),這個函數能夠將任何類型的值轉換為字符串。String()函數遵循下列轉換規則:

 

    如果值有toString()方法,則調用該方法(沒有參數)並返回相應的結果;

 

    如果值是null,則返回"null";

 

    如果值是undefined,則返回“undefined”

 

    下面再看幾個例子:

 

 

 

var value1=10;

 

var value2=true;

 

var value3=null;

 

 

 

alert(String(value1)); //"10"

 

alert(String(value2)); //"true"

 

alert(String(value3)); //"null"

 

alert(String(value4)); //"undefined"

 

 

 

    這里先后轉換了4個值:數值、布爾值、null和undefined。數值和布爾值的轉換結果與調用toString()方法得到的結果相同。因為null和undefined沒有toString()方法,所以String()函數就返回了這兩個值的字面量。

 

 

 

 

 

 

 

 

 

ECMAScript中的對象是可變的鍵控集合(即一組數據和功能的集合)。它將很多值聚合在一起,可通過名字訪問這些值。對象也可看做屬性的容器,每個屬性都是一個名/值對。屬性的名字可以是包括空字符串在內的任意字符串。屬性值可以是除undefined值之外的任何值。對象最常見的用法是創建(create)、設置(set)、查找(query)、刪除(delete)、檢測(test)和枚舉(enumerate)他的屬性。

 

一、屬性類型

ECMA-262第5版在定義只有內部采用的特性時,描述了屬性的各種特征。為了表示特性時內部值,該規范把它們放在了兩對方括號中,例如:[[Enumerable]]。ECMAScript對象中有兩種屬性:數據屬性和訪問器屬性。

1.數據屬性

數據屬性包含一個數據值的位置。在這個位置可以讀取和寫入值。數據屬性有4個描述其行為的特性。

   a.[[Configurable]]:表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為訪問器屬性。這個特性默認值為true。

   b.[[Enumerable]]:表示能否通過for-in循環返回屬性。這個特性默認值為true。

   c.[[Writable]]:表示能否修改屬性的值。這個特性默認值為true。

   d.[[Value]]:包含這個屬性的數據值。讀取屬性值的時候,從這個位置讀;寫入屬性值的時候,把新值保存在這個位置。這個特性的默認值為undefined。

2.訪問器屬性:

   a.[[Configurable]]:表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為數據屬性。對於直接在對象上定義的屬性,這個特性的默認值為true.

   b.[[Enumerable]]:表示能否通過for-in循環返回屬性。對於直接在對象上定義的屬性,這個特性的默認值為true。

   c.[[Get]]:在讀取屬性時調用的函數。默認值為undefined。

   d.[[Set]]:在寫入屬性時調用的函數。默認值為undefined。

 

二、創建對象

1.通過new創建對象

new 運算符創建並初始化一個新對象。關鍵字new后跟隨一個函數調用。這里的函數稱做構造函數,構造函數用以初始化一個新創建的對象。JavaScript語言核心中的原始類型都包含內置構造函數。例如:


除了這些內置構造函數,用自定義構造函數來初始化新對象也是非常常見的。

 

2.對象字面量

創建對象最簡單的方式就是在JavaScript代碼中使用對象字面量。對象字面量是由若干名/值對組成的映射表,名/值對中間用冒號分隔,名/值對之間用 逗號分隔,整個映射表用花括號括起來,結構為:{屬性名1:屬性值1,屬性名2:屬性值2,……}。屬性名可以是JavaScript標識符也可以是字符 串字面量(包括空字符串)。屬性的值可以是任意類型的JavaScript表達式,表達式的值(可以是原始值也可以是對象值)就是這個屬性的值。請看示 例:

3.原型

我們創建的每個對象都有一個prototype(原型)屬性,這個屬性是一個指針,指向一個對象,而這個對象的用途是包含可以由特定類型的所有實例共享的屬 性和方法。如果按照字面意思來理解,那么prototype就是通過調用構造函數而創建的那個對象實例的原型對象。使用原型對象的好處是可以讓所有對象實 例共享它所包含的屬性和方法。換句話說,不必在構造函數中定義對象實例的信息,而是可以將這些信息直接添加到原型對象中,請看示例:

 

在此,我們將sayName()方法和所有屬性直接添加到了Person的prototype屬性中,構造函數變成了空函數。即使如此,也仍然可以通過調用構造函數來創建新對象,而且新對象還會具有相同的屬性和方法。但與構造函數不同的是,新對象的這些屬性和方法是由所有實例共享的。 換句話說,person1和person2訪問的都是同一組屬性和同一個sayName()函數。由於對象的原型牽扯到的知識點非常多且復雜,在此就不向大家闡述,我將會在以后的文章中為大家詳細講述原型(prototype)這一概念。除此之外,JavaScript還有一種 Object.create()方法來創建對象

 

三、基於對象屬性的各種操作

1.對象屬性的獲取

 

訪問對象屬性可以使用點表示法和方括號表示法。對於點(.)來說,右側必須是一個以屬性名稱命名的簡單標識符。對於方括號來說([]),方括號內必須是一個計算結果為字符串的表達式,這個字符串就是屬性的名字。請看示例:

當使用方括號時,我們說方括號內的表達式必須返回字符串。其實更嚴謹的說,表達式必須返回字符串或返回一個可以轉換為字符串的值(這個特點可以用於處理很多情況)。由此我們可以聯想到數組,這和數組獲取元素的方法極為相似,其實數組也是對象,只是其屬性名為數組下標而已。

 

2.屬性訪問錯誤

屬性訪問並不總是返回或設置一個值。查詢一個不存在的屬性並不會報錯,如果在對象o自身的屬性或繼承的屬性中均未找到屬性x,屬性訪問表達式o.x返回undefined。回想一下我們person對象有屬性"name",而沒有屬性"subname":

但是如果對象不存在,那么試圖查詢這個不存在的對象的屬性就會報錯。null和undefined值都沒有屬性,因此查詢這些值的屬性會報錯,請看示例:

除非確定person和person.subname都是(或在行為上)對象,否則不能寫這樣的表達式person.subname.length,因為這樣會報錯,下面提供了兩種避免出錯的方法:


第二種示例使用了 "&&"的一種復合語言習慣的用法,因此只有在person為真值(不能是null或者undefined)的情況下才會計算之后的值,&&的這一行為稱作“短路”。

當然,給null和undefined設置屬性也會報類型錯誤。給其他值設置屬性也不總是成功,有一些屬性時只讀的,不能重新復制,有一些對象不允許新增屬性,但讓人頗感意外的是,這些設置屬性的失敗操作不會報錯:

這是一個歷史遺留問題,這個bug在ECMAScript5的嚴格模式中已經修復。在嚴格模式中,任何失敗的屬性設置操作都會拋出一個類型錯誤異常。

 

3.刪除屬性

delete運算符可以刪除對象的屬性。它的操作數應當是一個屬性訪問表達式。讓人感到意外的是,delete只是斷開屬性和宿主對象的聯系,而不會去操作屬性中的屬性。

 

delete運算符只能刪除自有屬性,不能刪除繼承屬性(要刪除繼承屬性必須從定義這個屬性的原型對象上刪除它,而且這會影響到所有繼承自這個原型的對象)

    當delete表達式刪除成功或沒有任何副作用(比如刪除不存在的屬性)時,它返回true。如果delete后不是一個屬性訪問表達式,delete同樣返回true:

delete 不能刪除那些可配置性為false的屬性(盡管可以刪除不可擴展的可配置屬性)。某些內置對象的屬性是不可配置的,比如通過變量聲明和函數聲明創建的全局 對象的屬性。在嚴格模式中,刪除一個不可配置屬性會報一個類型錯誤。在非嚴格模式中,這些情況下的delete操作會返回false:

在非嚴格模式中刪除全局對象的可配置屬性時,可以省略對全局對象的引用,直接在delete操作符后跟隨要刪除的屬性名即可:

然后再嚴格模式中,delete后跟隨一個非法的操作數(比如x),則會報一個語法錯誤,因此必須顯式指定對象及其屬性:

 

4.枚舉屬性

for-in語句可用來遍歷一個對象中的所有屬性名。該枚舉過程將會列出所有的屬性——包括函數和你可能不關心的原型中的屬性——所以有必要過濾掉那些你不想要的值。最為常用的過濾器是hasOwnProperty方法,以及使用typeof來排除函數:

屬性名出現得順序是不確定的,因此要對任何可能出現的順序有所准備。如果你想要確保屬性以特定的順序出現,最好的辦法就是完全避免使用for-in語句,而是創建一個數組,在其中以正確的順序包含屬性名:


通過使用for而不是for-in ,可以得到我們想要的屬性,而不用擔心可能發掘出原型鏈中的屬性,並且我們按正確的順序獲得了它們的值。

 

 

轉載自:https://mp.weixin.qq.com/s/-nEBCHqgQVf1arFhHNpRLw(僅作為記錄參考,侵刪)

                                                                                                                                                                    time:2020  04  19


免責聲明!

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



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