Javascript筆記之對象

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"
相關文章
相關標籤/搜索