你不知道的js - 對象

一、對象有兩種形式定義:聲明文字形式和構造形式。數組

二、內置對象:js中有一些對象子類型,稱爲內置對象安全

var strprimitive = 'I am string';
typeof strprimitive;//'string'
strprimitive instanceof String; //false

var strobj = new String('I am string');
typeof strobj;
strobj instanceof String;

Object.prototype.toString.call(strobj); // [object string]

 typeof ,instanceof,Object.prototype.toString.call()區分對象類型函數

js中經過Object.prototype.toString方法----精確判斷對象的類型

一、在 JavaScript 裏使用 typeof 來判斷數據類型,只能區分基本類型,即 「number」,」string」,」undefined」,」boolean」,」object」 五種。spa

對於數組、函數、對象來講,其關係錯綜複雜,使用 typeof 都會統一返回 「object」 字符串。prototype

二、instanceof判斷對象類型,有點麻煩code

//對象
(a instanceof Object) && !(a instanceof Array) && !(a instanceof Function)
//數組
(a instanceof Object) && (a instanceof Array)
//函數
(a instanceof Object) && (a instanceof Function)

三、使用Object.prototype.toString方法對象

console.log(Object.prototype.toString.call("jerry"));//[object String]
console.log(Object.prototype.toString.call(12));//[object Number]
console.log(Object.prototype.toString.call(true));//[object Boolean]
console.log(Object.prototype.toString.call(undefined));//[object Undefined]
console.log(Object.prototype.toString.call(null));//[object Null]
console.log(Object.prototype.toString.call({name: "jerry"}));//[object Object]
console.log(Object.prototype.toString.call(function(){}));//[object Function]
console.log(Object.prototype.toString.call([]));//[object Array]
console.log(Object.prototype.toString.call(new Date));//[object Date]
console.log(Object.prototype.toString.call(/\d/));//[object RegExp]

全部類型都會獲得不一樣的字符串,幾乎完美。blog

 

那爲何不直接用obj.toString()呢?索引

這是由於toString爲Object的原型方法,而Array ,function等類型做爲Object的實例,都重寫了toString方法。不一樣的對象類型調用toString方法時,根據原型鏈的知識,調用的是對應的重寫以後的toString方法(function類型返回內容爲函數體的字符串,Array類型返回元素組成的字符串.....),而不會去調用Object上原型toString方法(返回對象的具體類型),因此採用obj.toString()不能獲得其對象類型,只能將obj轉換爲字符串類型;所以,在想要獲得對象的具體類型時,應該調用Object上原型toString方法。 ip

 四、內容

 

 var myObject = {
  a:2
 };
 myObject.a;//2
 myObject['a'];//2

 

若是要訪問myObject 中a位置上的值,咱們須要使用.操做符,或者[]操做符

.a語法一般被稱做屬性訪問,['a']語法一般被稱爲鍵訪問

區別在於.操做符要求屬性名知足標識符的命名規範,而[..]語法能夠接受任意UTF-8/Unicode字符串做爲屬性名

因爲[..]語法使用字符串來訪問屬性,因此能夠在程序中構造字符串

在對象中屬性名永遠是字符串

五、可計算屬性名

ES6增長了可計算屬性名,能夠在文字形式中使用[]包裹一個表達式看成屬性名。

 var prefix = "foo";
 var myObject = {
  [prefix+"bar"]:'hello',
  [prefix+"baz"]:'world'
 };
 myObject['foobar'];//hello
 myObject['foobaz'];//world

 六、數組

數組指望的是數值下標,也就是說值存儲的位置是非負整數

數組也是對象,因此雖然每一個下標都是整數,仍然能夠給數組添加屬性

 var myArray = ['foo',42,'bar'];
 myArray.baz = 'baz';
 myArray.length;//3
 myArray.baz;//'baz'

能夠看到雖然添加了命名屬性,數組的length值並無發生變化

若是你試圖向數組中添加一個屬性可是屬性名看起來很像一個數字,那它會變成一個數值下標

var myArray = ['foo',42,'bar'];
myArray['3'] = 'baz';
myArray.length;//4
myArray[3];//'baz'

七、複製對象

對於JSON安全的對象來講,有一種巧妙的複製方法:

JSON安全:也就是說能夠被序列化爲一個JSON字符串而且能夠根據這個字符串解析出一個結構和值徹底同樣的對象

var newObj = JSON.parse(JSON.stringfy(someObj));

這種方法須要保證對象是JSON安全的,因此只適用於部分狀況

淺複製易懂,問題少一些。

Object.assign(..)第一個參數是目標對象,以後能夠跟一個或多個源對象

八、屬性描述符

從ES5開始,全部屬性都具備了屬性描述符

var myObject = {
  a:2
}
Object.getOwnPropertyDescriptor(myObject,'a');

// {
// value: 2,
// writable: true,
// enumerable: true,
// configurable: true
// }

 可使用Object.defineProperty()來添加一個新屬性,或者修改一個已有屬性

Object.defineProperty(myObject,'a',{
    value: 2,
    writable: true,
    enumerable: true,
    configurable: true
});
myObject.a;//2

九、對象默認的[[Put]] 和[[Get]]操做分別能夠控制屬性值的設置和

在ES5中可使用getter和setter部分改寫默認操做,可是隻能應用在單個屬性上,沒法應用在整個對象上。getter是一個隱藏函數,會在獲取屬性值時調用,setter也是一個隱藏函數,會在設置屬性時調用。

var myObject = {
  get a() {
    return 2;
  }
};
myObject.a = 3;
myObject.a;//2

因爲咱們只定義了a的getter,因此對a的值進行設置時,set操做會忽略賦值操做,不會拋出錯誤。

即便有了合法的setter咱們定義的getter只會返回2。因此set操做沒有意義。

十、存在性

咱們能夠在不訪問屬性值的狀況下判斷對象中是否存在這個屬性

var myObject = {
  a:2
};
('a' in myObject);//true
('b' in myObject);//false

myObject.hasOwnProperty('a');// true
myObject.hasOwnProperty('b');//false

in 操做符會檢查屬性是否在對象及其[[Prototype]]原型鏈上,相比之下,hasOwnProperty()只會檢查屬性是否在myObject對象中,不會檢查[[Prototype]]鏈

注意:in實際上檢查的是某個屬性是否存在。對於數組:4 in [2,4,6] 並非true ,由於 [2,4,6] 包含的是屬性名0,1,2沒有4

 十一、枚舉

可枚舉就至關於 能夠出如今對象屬性的遍歷中

不影響存在性

for...in...這種枚舉不只會包含全部的數值索引還會包含全部可枚舉屬性

相關文章
相關標籤/搜索