您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關javascript中有哪些數據類型的內容。小編覺得挺實用的,因此分享給大家做個參考。一起跟隨小編過來看看吧。
js基本七種數據類型為:1、String類型,用于表示字符串;2、Number類型,用于表示數字;3、Boolean類型;4、Symbol類型,代表獨一無二的值;5、Undefined類型;6、Null類型;7、Object類型。
在 JavaScript 規(guī)范中,共定義了七種數據類型,分為 “基本類型” 和 “引用類型” 兩大類,如下所示:
下面將詳細介紹這七種數據類型的一些特性。
String 類型用于表示由零或多個 16 位 Unicode 字符組成的字符序列,即字符串 。
由于計算機只能處理數字,如果要處理文本,就必須先把文本轉換為數字才能處理。在計算機中,1個字節(jié)(byte)由 8個比特(bit)組成,所以 1 個字節(jié)能表示的最大整數就是 255,如果想表示更大整數,就必須用更多的字節(jié),比如 2 個字節(jié)可以表示的最大整數為 65535 。最早,只有 127 個字符被編碼到計算機里,也就是大小寫英文字母、數字和一些符號,這個編碼表被稱為 ASCII 編碼,比如大寫字母 A 的編碼是 65,小寫字母 z 的編碼是122。
但如果要表示中文字符,顯然一個字節(jié)是不夠的,至少需要兩個字節(jié)。所以,中國制定了 GB2312 編碼,用來表示中文字符?;谕瑯拥脑?,各個國家都制定了自己的編碼規(guī)則 。這樣就會出現一個問題,即在多語言混合的文本中,不同的編碼會出現沖突,導致亂碼出現 。
為了解決這個問題,Unicode 編碼應運而生,它把所有的語言都統(tǒng)一到一套編碼中,采用 2 個字節(jié)表示一個字符,即最多可以表示 65535 個字符,這樣基本上可以覆蓋世界上常用的文字,如果要表示更多的文字,也可以采用 4 個字節(jié)進行編碼,這是一種通用的編碼規(guī)范 。
因此,JavaScript 中的字符也采用 Unicode 來編碼 ,也就是說,JavaScript 中的英文字符和中文字符都會占用 2 個字節(jié)的空間大小 ,這種多字節(jié)字符,通常被稱為寬字符。
在 JavaScript 中,字符串是基本數據類型,本身不存任何操作方法 。為了方便的對字符串進行操作,ECMAScript 提供了一個基本包裝類型:String 對象 。它是一種特殊的引用類型,JS引擎每當讀取一個字符串的時候,就會在內部創(chuàng)建一個對應的 String 對象,該對象提供了很多操作字符的方法,這就是為什么能對字符串調用方法的原因 。
var name = 'JavaScript'; var value = name.substr(2,1);
當第二行代碼訪問變量 str 時,訪問過程處于一種讀取模式,也就是要從內存中讀取這個字符串的值。而在讀取模式中訪問字符串時,引擎內部會自動完成下列處理:
用偽代碼形象的模擬以上三個步驟:
var obj = new String('JavaScript'); var value = obj.substr(2,1); name = null;
可以看出,基本包裝類型是一種特殊的引用類型。它和普通引用類型有一個很重要的區(qū)別,就是對象的生存期不同 。使用 new 操作符創(chuàng)建的引用類型的實例,在執(zhí)行流離開當前作用域之前都一直保存在內存中。而自動創(chuàng)建的基本包裝類型的對象,則只存在于一行代碼的執(zhí)行瞬間,然后立即被銷毀。在 JavaScript 中,類似的基本包裝類型還有 Number、Boolean 對象 。
作為字符串的基本包裝類型,String 對象提供了以下幾類方法,用以操作字符串:
charCodeAt 的作用是獲取字符的 Unicode 編碼,俗稱 “Unicode 碼點”。fromCharCode 是 String 對象上的靜態(tài)方法,作用是根據 Unicode 編碼返回對應的字符。
var a = 'a'; // 獲取Unicode編碼 var code = a.charCodeAt(0); // 97 // 根據Unicode編碼獲取字符 String.fromCharCode(code); // a
通過 charCodeAt 獲取字符的 Unicode 編碼,然后再把這個編碼轉化成二進制,就可以得到該字符的二進制表示。
var a = 'a'; var code = a.charCodeAt(0); // 97 code.toString(2); // 1100001
對于字符串的提取操作,有三個相類似的方法,分別如下:
substr(start [, length]) substring(start [, end]) slice(start [, end])
從定義上看,substring 和 slice 是同類的,參數都是字符串的某個 start 位置到某個 end 位置(但 end 位置的字符不包括在結果中);而 substr 則是字符串的某個 start 位置起,數 length 個長度的字符才結束。二者的共性是:從 start 開始,如果沒有第 2 個參數,都是直到字符串末尾。
substring 和 slice 的區(qū)別則是:slice 可以接受 “負數”,表示從字符串尾部開始計數; 而 substring 則把負數或其它無效的數當作 0。
'hello world!'.slice(-6, -1) // 'world' 'hello world!'.substring("abc", 5) // 'hello'
substr 的 start 也可接受負數,也表示從字符串尾部計數,這點和 slice 相同;但 substr 的 length 則不能小于 1,否則返回空字符串?! ?/p>
'hello world!'.substr(-6, 5) // 'world' 'hello world!'.substr(0, -1) // ''
JavaScript 中的數字類型只有 Number 一種,Number 類型采用 IEEE754 標準中的 “雙精度浮點數” 來表示一個數字,不區(qū)分整數和浮點數 。
在 IEEE754 中,雙精度浮點數采用 64 位存儲,即 8 個字節(jié)表示一個浮點數 。其存儲結構如下圖所示:
指數位可以通過下面的方法轉換為使用的指數值:
從存儲結構中可以看出, 指數部分的長度是11個二進制,即指數部分能表示的最大值是 2047(211-1),取中間值進行偏移,用來表示負指數,也就是說指數的范圍是 [-1023,1024] 。因此,這種存儲結構能夠表示的數值范圍為 21024 到 2-1023 ,超出這個范圍的數無法表示 。21024 和 2-1023 轉換為科學計數法如下所示:
1.7976931348623157 × 10308
5 × 10-324
因此,JavaScript 中能表示的最大值是 1.7976931348623157 × 10308,最小值為 5 × 10-324 。
這兩個邊界值可以分別通過訪問 Number 對象的 MAX_VALUE 屬性和 MIN_VALUE 屬性來獲取:
Number.MAX_VALUE; // 1.7976931348623157e+308 Number.MIN_VALUE; // 5e-324
如果數字超過最大值或最小值,JavaScript 將返回一個不正確的值,這稱為 “正向溢出(overflow)” 或 “負向溢出(underflow)” 。
Number.MAX_VALUE+1 == Number.MAX_VALUE; //true Number.MAX_VALUE+1e292; //Infinity Number.MIN_VALUE + 1; //1 Number.MIN_VALUE - 3e-324; //0 Number.MIN_VALUE - 2e-324; //5e-324
在 64 位的二進制中,符號位決定了一個數的正負,指數部分決定了數值的大小,小數部分決定了數值的精度。
IEEE754 規(guī)定,有效數字第一位默認總是1 。因此,在表示精度的位數前面,還存在一個 “隱藏位” ,固定為 1 ,但它不保存在 64 位浮點數之中。也就是說,有效數字總是 1.xx...xx 的形式,其中 xx..xx 的部分保存在 64 位浮點數之中,最長為52位 。所以,JavaScript 提供的有效數字最長為 53 個二進制位,其內部實際的表現形式為:
(-1)^符號位 * 1.xx...xx * 2^指數位
這意味著,JavaScript 能表示并進行精確算術運算的整數范圍為:[-253-1,253-1],即從最小值 -9007199254740991 到最大值 9007199254740991 之間的范圍 。
Math.pow(2, 53)-1 ; // 9007199254740991 -Math.pow(2, 53)-1 ; // -9007199254740991
可以通過 Number.MAX_SAFE_INTEGER 和 Number.MIN_SAFE_INTEGER 來分別獲取這個最大值和最小值。
console.log(Number.MAX_SAFE_INTEGER) ; // 9007199254740991 console.log(Number.MIN_SAFE_INTEGER) ; // -9007199254740991
對于超過這個范圍的整數,JavaScript 依舊可以進行運算,但卻不保證運算結果的精度。
Math.pow(2, 53) ; // 9007199254740992 Math.pow(2, 53) + 1; // 9007199254740992 9007199254740993; //9007199254740992 90071992547409921; //90071992547409920 0.923456789012345678;//0.9234567890123456
計算機中的數字都是以二進制存儲的,如果要計算 0.1 + 0.2 的結果,計算機會先把 0.1 和 0.2 分別轉化成二進制,然后相加,最后再把相加得到的結果轉為十進制 。
但有一些浮點數在轉化為二進制時,會出現無限循環(huán) 。比如, 十進制的 0.1 轉化為二進制,會得到如下結果:
0.0001 1001 1001 1001 1001 1001 1001 1001 …(1001無限循環(huán))
而存儲結構中的尾數部分最多只能表示 53 位。為了能表示 0.1,只能模仿十進制進行四舍五入了,但二進制只有 0 和 1 , 于是變?yōu)?0 舍 1 入 。 因此,0.1 在計算機里的二進制表示形式如下:
0.0001100110011001100110011001100110011001100110011001101
用標準計數法表示如下:
(?1)0 × 2?4 × (1.1001100110011001100110011001100110011001100110011010)2
同樣,0.2 的二進制也可以表示為:
(?1)0 × 2?3 × (1.1001100110011001100110011001100110011001100110011010)2
在計算浮點數相加時,需要先進行 “對位”,將較小的指數化為較大的指數,并將小數部分相應右移:
0.1→ (?1)0 × 2?3 × (0.11001100110011001100110011001100110011001100110011010)2
0.2→ (?1)0 × 2?3 × (1.1001100110011001100110011001100110011001100110011010)2
最終,“0.1 + 0.2” 在計算機里的計算過程如下:
經過上面的計算過程,0.1 + 0.2 得到的結果也可以表示為:
(?1)0 × 2?2 × (1.0011001100110011001100110011001100110011001100110100)2
然后,通過 JS 將這個二進制結果轉化為十進制表示:
(-1)**0 * 2**-2 * (0b10011001100110011001100110011001100110011001100110100 * 2**-52); //0.30000000000000004 console.log(0.1 + 0.2) ; // 0.30000000000000004
這是一個典型的精度丟失案例,從上面的計算過程可以看出,0.1 和 0.2 在轉換為二進制時就發(fā)生了一次精度丟失,而對于計算后的二進制又有一次精度丟失 。因此,得到的結果是不準確的。
JavaScript 提供了幾個特殊數值,用于判斷數字的邊界和其他特性 。如下所示:
有 3 個函數可以把非數值轉換為數值,分別如下:
Number(value) parseInt(string [, radix]) parseFloat(string)
Number() 可以用于任何數據類型,而另兩個函數則專門用于把字符串轉換成數值。
對于字符串而言,Number() 只能對字符串進行整體轉換,而 parseInt() 和 parseFloat() 可以對字符串進行部分轉換,即只轉換第一個無效字符之前的字符。
對于不同數據類型的轉換,Number() 的處理也不盡相同,其轉換規(guī)則如下:
【1】如果是 Boolean 值,true 和 false 將分別被轉換為 1 和 0。
【2】如果是數字值,只是簡單的傳入和返回。
【3】如果是 null 值,返回 0。
【4】如果是 undefined,返回 NaN。
【5】如果是字符串,遵循下列規(guī)則:
【6】如果是對象,則調用對象的 valueOf() 方法,然后依照前面的規(guī)則轉換返回的值。如果轉換的結果是 NaN,則調用對象的 toString() 方法,然后再次依照前面的規(guī)則轉換返回的字符串值。
需要注意的是:
一元加操作符加號 “+” 和 Number() 具有同樣的作用。
在 ECMAScript 2015 規(guī)范中,為了實現全局模塊化,Number 對象重寫了 parseInt 和 parseFloat 方法,但和對應的全局方法并無區(qū)別。
Number.parseInt === parseInt; // true Number.parseFloat === parseFloat; // true
位運算作用于最基本的層次上,即按內存中表示數值的位來操作數值。ECMAScript 中的數值以64位雙精度浮點數存儲,但位運算只能作用于整數,因此要先將 64 位的浮點數轉換成 32 位的整數,然后再進行位運算,最后再將計算結果轉換成64位浮點數存儲。常見的位運算有以下幾種:
需要注意的是:
“有符號右移” 和 “無符號右移” 只在計算負數的情況下存在差異,>> 在符號位的右側補0,不移動符號位;而 >>> 是在符號位的左側補0,符號位發(fā)生移動和改變。
JavaScript 對數字進行四舍五入操作的 API 有 ceil,floor,round,toFixed,toPrecision 等,詳細介紹請參考:JavaScript 中的四舍五入
Boolean 類型只有兩個字面值:true 和 false 。 在 JavaScript 中,所有類型的值都可以轉化為與 Boolean 等價的值 。轉化規(guī)則如下:
Boolean([]); //true Boolean({}); //true Boolean(undefined); //false Boolean(null); //false Boolean(''); //false Boolean(0); //false Boolean(NaN); //false
除 Boolean() 方法可以返回布爾值外,以下 4 種類型的操作,也會返回布爾值。
當關系操作符的操作數使用了非數值時,要進行數據轉換或完成某些奇怪的操作。
'a' > 'b'; // false, 即 'a'.charCodeAt(0) > 'b'.charCodeAt(0) 2 > '1'; // true, 即 Number('1') = 1 true > 0; //true, 即 Number(true) = 1 undefined > 0; //false, Number(undefined) = NaN null < 0; //false, Number(null) = NaN new Date > 100; //true , 即 new Date().valueOf()
== 和 != 操作符都會先轉換操作數,然后再比較它們的相等性。在轉換不同的數據類型時,需要遵循下列基本規(guī)則:
=== 和 !== 操作符最大的特點是,在比較之前不轉換操作數 。它們的操作規(guī)則如下:
null === undefined; //false, 類型不同,直接返回 false [] === []; //false ,類型相同,值不相同,指針地址不同 a=[],b=a,a===b; //true, 類型相同,值也相等 1 !== '1' ; // true , 值相等,但類型不同 [] !== [] ; // true, 類型相同,但值不相等
布爾操作符屬于一元操作符,即只有一個分項。其求值過程如下:
!(2+3) ; // false !(function(){}); //false !([] && null && ''); //true
利用 ! 的取反的特點,使用 !! 可以很方便的將一個任意類型值轉換為布爾值:
console.log(!!0); //false console.log(!!''); //false console.log(!!(2+3)); //true console.log(!!([] && null && '')); //false
需要注意的是:
邏輯與 “&&” 和 邏輯或 “||” 返回的不一定是布爾值,而是包含布爾值在內的任意類型值。
如下所示:
[] && 1; //1 null && undefined; //null [] || 1; //[] null || 1; //1
邏輯操作符屬于短路操作符 。在進行計算之前,會先通過 Boolean() 方法將兩邊的分項轉換為布爾值,然后分別遵循下列規(guī)則進行計算:
[] && {} && null && 1; //null [] && {} && !null && 1 ; //1 null || undefined || 1 || 0; //1 undefined || 0 || function(){}; //function(){}
條件語句通過計算表達式返回一個布爾值,然后再根據布爾值的真假,來執(zhí)行對應的代碼。其計算過程如下:
if(arr.length) { } obj && obj.name ? 'obj.name' : '' while(arr.length){ }
Symbol 是 ES6 新增的一種原始數據類型,它的字面意思是:符號、標記。代表獨一無二的值 。
在 ES6 之前,對象的屬性名只能是字符串,這樣會導致一個問題,當通過 mixin 模式為對象注入新屬性的時候,就可能會和原來的屬性名產生沖突 。而在 ES6 中,Symbol 類型也可以作為對象屬性名,凡是屬性名是 Symbol 類型的,就都是獨一無二的,可以保證不會與其他屬性名產生沖突。
Symbol 值通過函數生成,如下所示:
let s = Symbol(); //s是獨一無二的值 typeof s ; // symbol
和其他基本類型不同的是,Symbol 作為基本類型,沒有對應的包裝類型,也就是說 Symbol 本身不是對象,而是一個函數。因此,在生成 Symbol 類型值的時候,不能使用 new 操作符 。
Symbol 函數可以接受一個字符串作為參數,表示對 Symbol 值的描述,當有多個 Symbol 值時,比較容易區(qū)分。
var s1 = Symbol('s1'); var s2 = Symbol('s2'); console.log(s1,s2); // Symbol(s1) Symbol(s2)
注意,Symbol 函數的參數只是表示對當前 Symbol 值的描述,因此,相同參數的 Symbol 函數的返回值也是不相等的?!?/p>
用 Symbol 作為對象的屬性名時,不能直接通過點的方式訪問屬性和設置屬性值。因為正常情況下,引擎會把點后面的屬性名解析成字符串。
var s = Symbol(); var obj = {}; obj.s = 'Jack'; console.log(obj); // {s: "Jack"} obj[s] = 'Jack'; console.log(obj) ; //{Symbol(): "Jack"}
Symbol 作為屬性名,該屬性不會出現在 for...in、for...of 循環(huán)中,也不會被 Object.keys()、Object.getOwnPropertyNames()、JSON.stringify() 返回。但是,它也不是私有屬性,有一個 Object.getOwnPropertySymbols() 方法,專門獲取指定對象的所有 Symbol 屬性名。
var obj = {}; var s1 = Symbol('s1'); var s2 = Symbol('s2'); obj[s1] = 'Jack'; obj[s2] = 'Tom'; Object.keys(obj); //[] for(var i in obj){ console.log(i); //無輸出 } Object.getOwnPropertySymbols(obj); //[Symbol(s1), Symbol(s2)]
另一個新的API,Reflect.ownKeys 方法可以返回所有類型的鍵名,包括常規(guī)鍵名和 Symbol 鍵名。
var obj = {}; var s1 = Symbol('s1'); var s2 = Symbol('s2'); obj[s1] = 'Jack'; obj[s2] = 'Tom'; obj.name = 'Nick'; Reflect.ownKeys(obj); //[Symbol(s1), Symbol(s2),"name"]
有時,我們希望重新使用同一個 Symbol 值,Symbol.for 方法可以做到這一點。它接受一個字符串作為參數,然后全局搜索有沒有以該參數作為名稱的 Symbol 值。如果有,就返回這個 Symbol 值,否則就新建并返回一個以該字符串為名稱的 Symbol 值。
var s1 = Symbol.for('foo'); var s2 = Symbol.for('foo'); s1 === s2 //true
Symbol.for() 也可以生成 Symbol 值,它 和 Symbol() 的區(qū)別是:
因此,Symbol.for() 永遠搜索不到 用 Symbol() 產生的值。
var s = Symbol('foo'); var s1 = Symbol.for('foo'); s === s1; // false
Symbol.keyFor() 方法返回一個已在全局環(huán)境中登記的 Symbol 類型值的 key 。
var s1 = Symbol.for('s1'); Symbol.keyFor(s1); //foo var s2 = Symbol('s2'); //未登記的 Symbol 值 Symbol.keyFor(s2); //undefined
Undefined 是 Javascript 中特殊的原始數據類型,它只有一個值,即 undefined,字面意思是:未定義的值 。它的語義是,希望表示一個變量最原始的狀態(tài),而非人為操作的結果 。 這種原始狀態(tài)會在以下 4 種場景中出現:
var foo; console.log(foo); //undefined
訪問 foo,返回了 undefined,表示這個變量自從聲明了以后,就從來沒有使用過,也沒有定義過任何有效的值,即處于一種原始而不可用的狀態(tài)。
console.log(Object.foo); // undefined var arr = []; console.log(arr[0]); // undefined
訪問 Object 對象上的 foo 屬性,返回 undefined , 表示Object 上不存在或者沒有定義名為 foo 的屬性。數組中的元素在內部也屬于對象屬性,訪問下標就等于訪問這個屬性,返回 undefined ,就表示數組中不存在這個元素。
// 函數定義了形參 a function fn(a) { console.log(a); //undefined } fn(); // 未傳遞實參
函數 fn 定義了形參 a, 但 fn 被調用時沒有傳遞參數,因此,fn 運行時的參數 a 就是一個原始的、未被賦值的變量。
void 0 ; // undefined void false; // undefined void []; // undefined void null; // undefined void function fn(){} ; // undefined
ECMAScript 明確規(guī)定 void 操作符 對任何表達式求值都返回 undefined ,這和函數執(zhí)行操作后沒有返回值的作用是一樣的,JavaScript 中的函數都有返回值,當沒有 return 操作時,就默認返回一個原始的狀態(tài)值,這個值就是 undefined,表明函數的返回值未被定義。
因此,undefined 一般都來自于某個表達式最原始的狀態(tài)值,不是人為操作的結果。當然,你也可以手動給一個變量賦值 undefined,但這樣做沒有意義,因為一個變量不賦值就是 undefined 。
Null 是 Javascript 中特殊的原始數據類型,它只有一個值,即 null,字面意思是:“空值” 。它的語義是,希望表示一個對象被人為的重置為空對象,而非一個變量最原始的狀態(tài) 。 在內存里的表示就是,棧中的變量沒有指向堆中的內存對象。當一個對象被賦值了 null 以后,原來的對象在內存中就處于游離狀態(tài),GC 會擇機回收該對象并釋放內存。因此,如果需要釋放某個對象,就將變量設置為 null,即表示該對象已經被清空,目前無效狀態(tài)。
null 是原始數據類型 Null 中的唯一一個值,但 typeof 會將 null 誤判為 Object 類型 。
typeof null == 'object'
在 JavaScript 中,數據類型在底層都是以二進制形式表示的,二進制的前三位為 0 會被 typeof 判定為對象類型,如下所示:
而 null 值的二進制表示全是 0 ,自然前三位當然也是 000,因此,typeof 會誤以為是對象類型。如果想要知道 null 的真實數據類型,可以通過下面的方式來獲取。
Object.prototype.toString.call(null) ; // [object Null]
在 ECMAScript 規(guī)范中,引用類型除 Object 本身外,Date、Array、RegExp 也屬于引用類型 。
引用類型也即對象類型,ECMA262 把對象定義為:無序屬性的集合,其屬性可以包含基本值、對象或者函數。 也就是說,對象是一組沒有特定順序的值 。由于其值的大小會改變,所以不能將其存放在棧中,否則會降低變量查詢速度。因此,對象的值存儲在堆(heap)中,而存儲在變量處的值,是一個指針,指向存儲對象的內存處,即按址訪問。具備這種存儲結構的,都可以稱之為引用類型 。
由于引用類型的變量只存指針,而對象本身存儲在堆中 。因此,當把一個對象賦值給多個變量時,就相當于把同一個對象地址賦值給了每個變量指針 。這樣,每個變量都指向了同一個對象,當通過一個變量修改對象,其他變量也會同步更新。
var obj = {name:'Jack'}; var obj2 = obj; obj2.name = 'Tom' console.log(obj.name,obj2.name); //Tom,Tom
ES6 提供了一個原生方法用于對象的拷貝,即 Object.assign() 。
var obj = {name:'Jack'}; var obj2 = Object.assign({},obj); obj2.name = 'Tom' console.log(obj.name,obj2.name); //Jack Tom
需要注意的是,Object.assign() 拷貝的是屬性值。當屬性值是基本類型時,沒有什么問題 ,但如果該屬性值是一個指向對象的引用,它也只能拷貝那個引用值,而不會拷貝被引用的那個對象。
var obj = {base:{name:'Jack'}}; var obj2 = Object.assign({},obj); obj2.base.name = 'Tom' console.log(obj.base.name,obj2.base.name); //Tom Tom
從結果可以看出,obj 和 obj2 的屬性 base 指向了同一個對象的引用。因此,Object.assign 僅僅是拷貝了一份對象指針作為副本 。這種拷貝被稱為 “一級拷貝” 或 “淺拷貝” 。
如果要徹底的拷貝一個對象作為副本,兩者之間的操作相互不受影響,則可以通過 JSON 的序列化和反序列化方法來實現 。
var obj = {base:{name:'Jack'}}; var obj2 = JSON.parse(JSON.stringify(obj)) obj2.base.name = 'Tom' console.log(obj.base.name,obj2.base.name); //Jack Tom
這種拷貝被稱為 “多級拷貝” 或 “深拷貝” 。
ECMA-262 第 5 版定義了一些內部特性(attribute),用以描述對象屬性(property)的各種特征。ECMA-262 定義這些特性是為了實現 JavaScript 引擎用的,因此在 JavaScript 中不能直接訪問它們。為了表示特性是內部值,該規(guī)范把它們放在了兩對兒方括號中,例如[[Enumerable]]。 這些內部特性可以分為兩種:數據屬性 和 訪問器屬性 。
數據屬性包含一個數據值的位置,在這個位置可以讀取和寫入值 。數據屬性有4個描述其行為的內部特性:
要修改屬性默認的特性,必須使用 ECMAScript 5 的 Object.defineProperty() 方法。這個方法接收三個參數:屬性所在的對象、屬性的名字和一個描述符對象。其中,描述符(descriptor)對象的屬性必須是:configurable、enumerable、writable 和 value。設置其中的一或多個值,可以修改對應的特性值。例如:
var person = {}; Object.defineProperty(person, "name", { writable: false, value: "Nicholas" }); console.log(person.name); //"Nicholas" person.name = "Greg"; console.log(person.name); //"Nicholas"
在調用 Object.defineProperty() 方法時,如果不指定 configurable、enumerable 和 writable 特性,其默認值都是 false 。
訪問器屬性不包含數據值,它們包含一對 getter 和 setter 函數(不過,這兩個函數都不是必需的)。在讀取訪問器屬性時,會調用getter 函數,這個函數負責返回有效的值;在寫入訪問器屬性時,會調用setter 函數并傳入新值,這個函數負責決定如何處理數據。訪問器屬性有如下4 個特性。
訪問器屬性不能直接定義,也必須使用 Object.defineProperty() 來定義。請看下面的例子:
var book = { _year: 2004 }; Object.defineProperty(book, "year", { get: function () { return this._year; }, set: function (newValue) { if (newValue > 2004) { this._year = newValue; console.log('set new value:'+ newValue) } } }); book.year = 2005; //set new value:2005
ECMA-262 第 5 版對 Object 對象進行了增強,包括 defineProperty 在內,共定義了 9 個新的 API:
感謝各位的閱讀!關于javascript中有哪些數據類型就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。