JavaScript權威指南之對象

創建對象

1.對象直接量

var obj = {
	name: 'xiaoming',
	age: 20
};

2.關鍵字new

var obj = new Object();

3.Object.create函數

var obj = Object.create(Object.prototype);

實現原理:

/*
*@params {object} p
@returns {object}
*/
var _create (p) {
	function f() {};
	f.prototype = p;    //將原型指向傳進來的對象
	return new f();
}

對象屬性的設置和訪問

可以通過".“或者”[]“進行設置和訪問;
如果屬性是關鍵字、保留字、包含着”-",“ ”(空白字符串),或者是接收一個屬性是變量的情況,需要使用"[]"進行操作對象;

var obj = {
	"main title": "This is my name",
	"for": 1,
	"main-title: "This is title",
	"class": 2
};
obj[xxx]; //以上等情況都是使用[]進行訪問

訪問對象屬性(重點)
訪問一個對象的屬性,會先從對象的“自有屬性”開始查找,如果找到,就往對象的原型上查找,如果沒有則一直往上查找直至**‘Object.prototype.__ proto __’**(null)。如果查找的過程找到,則返回對應的值。沒有的話,則返回undefined。
1.如果屬性是原型上繼承而來且同時是隻讀屬性,則只能讀取該屬性的值而不是給其賦值。
2.如果屬性不是對象的自有屬性,同時該對象繼承的原型對象上有該屬性,且該屬性的修改符writable爲true,且同時定義了setter函數,那麼給該屬性賦值的時候調用了setter函數

//上述規則1
var obj = {};
Object.defineProperty(obj, a, {
	value: 1,
	writable: false,    //false爲只讀,true爲可讀寫
	configurable: false,//false爲不可刪除或重新修改屬性的描述符,true可刪除或重新定義該屬性
	enumerable: false,   //false爲不可枚舉,true爲可枚舉
});


var myObj = Object.create(obj);
myObj.a = 100;   //無效,該屬性爲原型上且writable爲false,只能對其進行訪問
myObj.a;         // 1

//上述規則2
var obj = {
    x: 1,
    y: 2
}; 
var value = 1;
Object.defineProperty(obj, 'z', {
    set: function (val) {
        console.log(`set value to ${val}`);
        value = val;
    },
    get: function () {
        console.log(`get value is ${value}`);
        return value;
    }
});

var childObj = Object.create(obj);
childObj.a = 100;     ///調用的是繼承對象的setter屬性

刪除對象屬性

delete操作符只能刪除對象的自有屬性而不能刪除繼承屬性。
delete刪除成功或者刪除不存在的屬性會返回true。
delete刪除不可配置(configurable)爲false的屬性,返回false。嚴格模式直接拋出錯誤。

檢測屬性

運算符有以下這些:

in 操作符
檢測對象所有自有屬性和繼承屬性,存在爲true

hasOwnProperty 操作符
檢測對象所有自有屬性,存在爲true

propertyIsEumerable 操作符
檢測對象所有不可枚舉自有屬性,存在爲true

枚舉屬性

for/in 
遍歷對象所有可枚舉的自有屬性和繼承屬性

Object.keys()
獲取對象所有可枚舉的自有屬性

Object.getOwnPropertyNames()
獲取對象所有自有屬性

getter和setter屬性

如果某個屬性只存在getter,那該屬性就是隻讀屬性;如果某個屬性只存在setter,那該屬性就是隻寫屬性;同時存在的

var obj = {
	x: 1,
	y: 2,
	get r () {
		return this.x + this.y;
	},
	set r (val) {
		this.x = val / 2;
		this.y = val / 3;
	}
};
等價於:
var obj = {
	x: 1,
	y: 2
};
Object.defineProperty(obj, 'z', {
    get () {
        return this.x + this.y;
    },
    set (val) {
        this.x = val / 2;
        this.y = val / 3;
    }
});

屬性的特性

對象屬性分爲兩種:數據屬性和存取器屬性,屬性具有屬性描述符,也就是下面列舉的這些。

數據屬性描述符:
value 值
enumerable 可枚舉的
configurable 可配置的
writable 可寫的
存取器屬性描述符:
set 寫入
get 讀取
enumerable 可枚舉的
configurable 可配置的
Object.getOwnPropertyDescriptor(obj,key);
只能獲取自有屬性的屬性描述符

Object.getPropertyOf(obj);
獲取對象的原型對象

Object.defineProperty(Obj, key, descriptor);
定義對象某個屬性,新創建的屬性默認屬性描述符的特性爲false或者undefined

Object.defineProperties(obj, {多個屬性描述符});
定義對象多個屬性

對象的三個屬性

原型屬性
獲取原型對象
ES5: Object.getPropertyOf()
ES3: obj.constructor.prototype
檢測一個對象是否爲另外一個對象的原型
p.isPropertyOf(o) //檢測p是否爲o的原型
instanceof 運算符用於檢測構造函數的 prototype 屬性是否出現在某個實例對象的原型鏈上
例子:
function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
const auto = new Car('Honda', 'Accord', 1998);
console.log(Car.prototype.isPrototypeOf(auto)); //true
console.log(auto instanceof Car); //true
類屬性
Object.prototype.toString.call(o).slice(8, -1); //返回類屬性
可擴展性

對象的可擴展性是表示能否給對象添加新屬性。

Object.esExtensible(); // 查詢對象是否可擴展
Object.preventExtensions(); //將對象轉換爲不可擴展,但是屬性還是可配置的
Object.seal(); //將對象轉換爲不可擴展,而且對象的自有屬性也是不可配置的,屬性的讀寫屬性依然有效
Object.freeze(); //將對象轉換爲不可擴展,而且對象的自有屬性變爲只讀屬性

序列化對象

JSON.stringify()將對象轉換爲字符串;
JSON.parse()將對字符串轉換爲對象;

NaN,Infinity, -Infinity轉換爲字符串都變成null
函數、RegExp、Error對象和undefined不能被序列化和還原
只序列化對象的自有屬性

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章