1.對象的結構:json
對象中包含一系列屬性,這些屬性是無序的。每一個屬性都有一個字符串key和對應的value。對象有2種訪問方式,以下圖所示:數組
var obj = {}; obj[1] = 1; obj['1'] = 2; obj; // Object {1: 2} var obj = {}; obj.y = 2; obj.x = 1; obj ; //{y: 2, x: 1}
2.建立對象的方式dom
2.1.經過字面量的方式來建立對象,以下圖所示,那麼訪問對象的時候就能夠經過obj2.z的方式來訪問函數
var obj2 = { x : 1, y : 2, o : { z : 3, n : 4 } };
2.2.經過new/原型鏈的方式來建立對象,經過繼承的方式來建立對象,下面的代碼中,foo至關於父類,obj至關於子類,foo中定義了z屬性,當在子類訪問一個子類中未定義的屬性時,會向上查找,查找父類中的prototype屬性中是否存在該屬性,可以查找到該屬性,可是這個屬性並不屬於子類。this
function foo(){} foo.prototype.z = 3;
//建立對象 var obj =new foo(); obj.y = 2; obj.x = 1; obj.x; // 1 obj.y; // 2 obj.z; // 3 typeof obj.toString; // ‘function' 'z' in obj; // true obj.hasOwnProperty('z'); // false
可是當子類中從新定義prototype中對應的屬性時,obj.hasOwnProperty()函數就返回true,刪除屬性的時候就只能刪除自身定義的屬性,不能刪除父類中定義的屬性spa
obj.z = 5; obj.hasOwnProperty('z'); // true foo.prototype.z; // still 3 obj.z; // 5
obj.z = undefined; obj.z; // undefined delete obj.z; // true obj.z; // 3
2.3經過Object.create方式建立對象,以下面的代碼所示,這種 方式和上面的方式是有一點不一樣的,具體看下面的圖。prototype
var obj = Object.create({x : 1}); obj.x // 1 typeof obj.toString // "function" obj.hasOwnProperty('x');// false
var obj = Object.create(null); obj.toString // undefined
3.屬性操做的幾種方式code
3.1屬性讀寫,屬性讀寫通常有2種方式,數組或者經過運算符.來讀寫屬性,以下面的代碼所示,通常用運算符.可是出現一次順序排列的key時,推薦採用數組的形式來訪問對象。對象
var obj = {x : 1, y : 2}; obj.x; // 1 obj["y"]; // 2 obj["x"] = 3; obj.y = 4; var obj = {x1 : 1, x2 : 2}; var i = 1, n = 2; for (; i <= n; i++) { console.log(obj['x' + i]); }
這裏,還要注意一個小小的坑,就是用for來對 對象進行遍歷時,enumrable屬性爲false的對象是不會出如今遍歷列表中的。blog
var p; for (p in obj) { console.log(obj[p]); }
還要一個寫代碼的小技巧是,在對對象訪問時候,先判斷該對象是否爲空,是否具備該屬性
var obj = {x : 1}; obj.y; // undefined var yz = obj.y.z; // TypeError: Cannot read property 'z' of undefined obj.y.z = 2; // TypeError: Cannot set property 'z' of undefined
因此推薦下面的方式來訪問,先作判斷:
var yz; if (obj.y) { yz = obj.y.z; } var yz = obj && obj.y && obj.y.z;
3.2 屬性刪除,直接用delelte刪除對象的屬性,configurable爲false的屬性不能刪除,以下圖中的Object.prototype
var person = {age : 28, title : 'fe'}; delete person.age; // true delete person['title']; // true person.age; // undefined delete person.age; // true delete Object.prototype; // false, var descriptor = Object.getOwnPropertyDescriptor(Object, 'prototype'); descriptor.configurable; // false
3.3 屬性檢測,經過屬性檢測能夠判斷對象中存不存在對應的屬性,經過hasOwnProperty()或者propertyIsEnumerable()方法來判斷, 以下圖中代碼所示:
var cat = new Object; cat.legs = 4; cat.name = "Kitty"; 'legs' in cat; // true 'abc' in cat; // false "toString" in cat; // true, inherited property!!! cat.hasOwnProperty('legs'); // true cat.hasOwnProperty('toString'); // false cat.propertyIsEnumerable('legs'); // true cat.propertyIsEnumerable('toString'); // false
經過Object.defineProperty()方法能夠自定義對象的屬性,以下圖中代碼所示:
Object.defineProperty(cat, 'price', {enumerable : false, value : 1000}); cat.propertyIsEnumerable('price'); // false cat.hasOwnProperty('price'); // true
接下來講明!=與!==的區別,以下圖中所示,!=模式下,undefined與null相同,但在!==嚴格模式下,undefined與null不一樣
3.4 屬性枚舉,主要用在用for來遍歷對象中的屬性時,以下圖的代碼,propertyIsEnumerable屬性爲false的屬性在遍歷時,不會被遍歷出來。 Object.keys(person)來遍歷對象中的key也是同樣的
var o = {x : 1, y : 2, z : 3}; 'toString' in o; // true o.propertyIsEnumerable('toString'); // false var key; for (key in o) { console.log(key); // x, y, z } var obj = Object.create(o); obj.a = 4; var key; for (key in obj) { console.log(key); // a, x, y, z } var obj = Object.create(o); obj.a = 4; var key; for (key in obj) { if (obj.hasOwnProperty(key)) { console.log(key); // a } }
4.getter和setter介紹
若對象中的某些屬性,不想暴露,可使用set,get方式來進行屬性訪問,以下圖的代碼所示:
var man = { name : 'Bosn', weibo : '@Bosn', get age() { return new Date().getFullYear() - 1988; }, set age(val) { console.log('Age can\'t be set to ' + val); } } console.log(man.age); // 27 man.age = 100; // Age can't be set to 100 console.log(man.age); // still 27
還有更復雜一點的set 和get方式,
var man = { weibo : '@Bosn', $age : null, get age() { if (this.$age == undefined) { return new Date().getFullYear() - 1988; } else { return this.$age; } }, set age(val) { val = +val; if (!isNaN(val) && val > 0 && val < 150) { this.$age = +val; } else { throw new Error('Incorrect val = ' + val); } } } console.log(man.age); // 27 man.age = 100; console.log(man.age); // 100; man.age = 'abc'; // error:Incorrect val = NaN
get和set 方式還能夠和原型鏈進行結合,將幫助咱們更好地理解對象的屬性
function foo() {} Object.defineProperty(foo.prototype, 'z', {get : function(){return 1;}}); var obj = new foo(); obj.z; // 1 obj.z = 10; obj.z; // still 1
Object.defineProperty(obj, 'z', {value : 100, configurable: true}); obj.z; // 100; delete obj.z; obj.z; // back to 1
var o = {}; Object.defineProperty(o, 'x', {value : 1}); // writable=false, configurable=false var obj = Object.create(o); obj.x; // 1 obj.x = 200; obj.x; // still 1, can't change it
Object.defineProperty(obj, 'x', {writable:true, configurable:true, value : 100}); obj.x; // 100 obj.x = 500; obj.x; // 500
5.屬性標籤
這裏主要介紹經過Object.getOwnPropertyDescriptor( )方法來獲取對象的屬性的標籤
Object.getOwnPropertyDescriptor({pro : true}, 'pro'); // Object {value: true, writable: true, enumerable: true, configurable: true} Object.getOwnPropertyDescriptor({pro : true}, 'a'); // undefined
當須要同時定義多個屬性時候,能夠經過Object.defineProperties()方式,以下圖所示:
Object.defineProperties(person, { title : {value : 'fe', enumerable : true}, corp : {value : 'BABA', enumerable : true}, salary : {value : 50000, enumerable : true, writable : true}, luck : { get : function() { return Math.random() > 0.5 ? 'good' : 'bad'; } }, promote : { set : function (level) { this.salary *= 1 + level * 0.1; } } }); Object.getOwnPropertyDescriptor(person, 'salary'); // Object {value: 50000, writable: true, enumerable: true, configurable: false} Object.getOwnPropertyDescriptor(person, 'corp'); // Object {value: "BABA", writable: false, enumerable: true, configurable: false} person.salary; // 50000 person.promote = 2; person.salary; // 60000
下面這張圖詳細描述了屬性標籤
7.序列化和對象方法
經過JSON.stringify()方法來讓對象序列化,經過JSON.parse()方法來是json字符串轉換爲json對象。
var obj = {x : 1, y : true, z : [1, 2, 3], nullVal : null}; JSON.stringify(obj); // "{"x":1,"y":true,"z":[1,2,3],"nullVal":null}" obj = {val : undefined, a : NaN, b : Infinity, c : new Date()}; JSON.stringify(obj); // "{"a":null,"b":null,"c":"2015-01-20T14:15:43.910Z"}" obj = JSON.parse('{"x" : 1}'); obj.x; // 1
經過 字符串+對象的方式能夠自動調用對象的toString()或者valueOf()方法,以下圖中代碼所示:
var obj = {x : 1, y : 2}; obj.toString(); // "[object Object]" obj.toString = function() {return this.x + this.y}; "Result " + obj; // "Result 3", by toString +obj; // 3, from toString obj.valueOf = function() {return this.x + this.y + 100;}; +obj; // 103, from valueOf "Result " + obj; // still "Result 3"