創建物件
物件直接量
物件直接量是由若干名/值對組成的映射表,名/值對中間用冒號分隔,名/值對之間用逗號分隔,整個映射表用花括號括起來,
var empty = {};
var point = { x:0, y:0};
var point2 = {x:point.x, y:point.y+1};
var book = {
"main title":"JavaScript",
//屬性名字里有空格,必須用字串表示
"sub-title":"The",
//屬性名字里有連字符,必須用字串表示
"for":"all",
//"for"是保留字,必須用字串表示
author:{
//這個屬性的值是一個物件
name:"123"
//注意,在里的屬性名都沒有引號
}
};
通過new創建物件
var o = new Object();
//創建一個空物件,和{}一樣
var a = new Array();
//創建一個空陣列,和[]一樣
var d = new Date();
//創建一個表示當前時間的Date物件
var r = new RegExp("js");
//創建一個可以進行匹配的RegExp物件
原型
所有通過物件直接量創建的物件都具有同一個原型物件,并可以通過JavaScript代碼Object.prototype獲得對原型物件的參考,通過關鍵字new和建構式呼叫創建的物件的原型就是建構式的prototype屬性的值,因此,同使用{}創建物件一樣,通過new Object()創建的物件也繼承自Object.prototype,同樣,通過new Array()創建的物件的原型就是Array.prototype,通過new Date()創建的物件的原型就是Date.prototype,
沒有原型的物件為數不多,Object.prototype就是其中之一,它不繼承任何屬性,其他原型物件都是普通物件,普通物件都具有原型,所有的內置建構式(以及大部分自定義的建構式)都具有一個繼承自Object.prototype的原型,例如,Date.prototype的屬性繼承自Object.prototype,因此由new Date()創建的Date物件的屬性同時繼承自Date.prototype和Object.prototype,這一系列鏈接的原型物件就是所謂的“原型鏈”(prototype chain),
Object.create()
創建一個新物件,其中第一個引數是這個物件的原型,Object.create()提供第二個可選引數,用以對物件的屬性進行進一步描述,
Object.create()是一個靜態函式,而不是提供給某個物件呼叫的方法,使用它的方法很簡單,只須傳入所需的原型物件即可:
var AB = Object.create({x:1,y:2});
屬性的查詢和設定
var a = book.author;
//得到book的"author"屬性
book.edition = 6;
//給book創建一個名為"edition"的屬性并賦值
book["main title"] = "123"
//給"main title"屬性賦值
繼承
假設要查詢物件o的屬性x,如果o中不存在x,那么將會繼續在o的原型物件中查詢屬性x,如果原型物件中也沒有x,但這個原型物件也有原型,那么繼續在這個原型物件的原型上執行查詢,直到找到x或者查找到一個原型是null的物件為止,
var o = {}
o.x = 1;//給o定義一個屬性x
var p = inherit(o);//p繼承o
p.y = 2;//給p定義一個屬性y
var q = inherit(p);//q繼承p
q.z = 3;//給q定義一個屬性z
q.x + q.y // 3 x和y分別繼承自o和p
屬性賦值操作首先檢查原型鏈,以此判定是否允許賦值操作,如果允許屬性賦值操作,它也總是在原始物件上創建屬性或對已有的屬性賦值,而不會去修改原型鏈,
var u = { r:1 };
var c = inherit(u);
c.x = 1; c.y =1;
c.r =2;
u.r; // 1 原型物件沒有修改
屬性訪問錯誤
當book沒有a屬性
book.a // undefined
var l = book.a.length;
//拋出一個型別錯誤例外,undefined沒有屬性
洗掉屬性
delete運算子可以洗掉物件的屬性,
delete book.author;
//book不再有屬性author
delete book["main title"];
//book不再有屬性"main title"
delete運算子只能洗掉自有屬性,不能洗掉繼承屬性(要洗掉繼承屬性必須從定義這個屬性的原型物件上洗掉它,而且這會影響到所有繼承自這個原型的物件),
當delete運算式洗掉成功或沒有任何副作用(比如洗掉不存在的屬性)時,它回傳true,如果delete后不是一個屬性訪問運算式,delete同樣回傳true:
o = {x:1};
delete o.x; //洗掉x,回傳true
delete o.x; //什么都沒做(x已經不存在了),回傳true
delete o.toString; //什么也沒做(toString是繼承來的),回傳true
delete 1; //無意義,回傳true
delete不能洗掉那些可配置性為false的屬性
在這些情況下的delete操作會回傳false:
delete Object.prototype;//不能洗掉,屬性是不可配置的
var x = 1; //宣告一個全域變數
delete this.x; //不能洗掉這個屬性
function f (){}//宣告一個全域函式
delete this.f; //也不能洗掉全域函式
檢測驗性
in運算子的左側是屬性名(字串),右側是物件,如果物件的自有屬性或繼承屬性中包含這個屬性則回傳true:
var o = { x:1 }
"x" in o; //true "x"是o的屬性
"y" in o; //false "y"不是o的屬性
"toString" in o; //true o繼承toString屬性
物件的hasOwnProperty()方法用來檢測給定的名字是否是物件的自有屬性,對于繼承屬性它將回傳false:
var o = { x:1 }
o.hasOwnProperty("x");//true o有一個自有屬性x
o.hasOwnProperty("y");//false o中不存在屬性y
o.hasOwnProperty("toString");//false toString是繼承屬性
propertyIsEnumerable()是hasOwnProperty()的增強版,只有檢測到是自有屬性且這個屬性的可列舉性(enumerable attribute)為true時它才回傳true,
var o = inherit({ y:2});
o.x = 1;
o.propertyIsEnumerable("x"); //true o有一個可列舉的自有屬性x
o.propertyIsEnumerable("y"); //false y是繼承來的
Object.propertyIsEnumerable("toString"); //false 不可列舉
除了使用in運算子之外,另一種更簡便的方法是使用“!==”判斷一個屬性是否是undefined:
var o = { x:1 }
o.x !== undefined; //true o中有屬性x
o.y !== undefined; //false o中沒有屬性y
o.toString !== undefined; //true o繼承了toString屬性
序列化物件
物件序列化(serialization)是指將物件的狀態轉換為字串,也可將字串還原為物件,ECMAScript 5提供了內置函式JSON.stringify()和JSON.parse()用來序列化和還原JavaScript物件,這些方法都使用JSON作為資料交換格式,JSON的全稱是“JavaScript Object Notation”
o = {x:1, y:{z:[false,null,""]}};
s = JSON.stringify(o);
//s是'{"x":1,"y":{"z":[false,null,""]}}'
p = JSON.parse(s);
// p == o
參考資料:《JavaScript權威指南》
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/294246.html
標籤:其他
上一篇:3.1 前端學習筆記之XML與HTML、JavaScript、jQuery、AJAX、JSON的區別
下一篇:JavaScript|異步編程
