原型
創(chuàng)建新對象
Object.create(Object.prototype)
;
屬性查詢和設(shè)置
通過"."或方括號來獲取屬性的值,值得注意的是使用方括號時里面的值是以屬性命名的字符串腊凶,用方括號有點類似于數(shù)組。
var age=mianmian["age"]; //獲取年齡屬性弓摘;
var age=mianmian.age;
繼承
先看一小段代碼
var o={};
o.x=1;
var p=inherit(o);
var q=inherit(p);
console.log(q.x); //1;
發(fā)現(xiàn)什么 了沒有栽连,就是在查找繼承的時候是從下往上一層一層的查找原型的翩伪,當(dāng)找到x時即返回值,停止眉尸。對象的原型屬性就像一個“鏈”域蜗,這個鏈實現(xiàn) 屬性的繼承。
在js中噪猾,只有在查詢屬性的時候才會體會到繼承的存在霉祸,而設(shè)置屬性與繼承無關(guān)無法通過繼承的屬性值的改變來改變原型的值;
var o={};
o.x=3;
var m=inherit(o);
function inherit(p) { //繼承函數(shù)
if(p==null) throw TypeError();
if(Object.create) return Object.create(p);
var t=typeof p;
if(t!=="object"&&t!=="function") throw TypeError();
function f() {};
f.prototype=p;
return new f();
}
m.x=9;
console.log(o.x); //3袱蜡,未改變原始值
刪除屬性
delete只能刪除自有屬性丝蹭,不能刪除繼承屬性,要刪除繼承屬性必須從定義這個屬性的原型對象上刪除它坪蚁,而且會影響所有繼承自這個原型的對象
function Mianmian(name,age) {
this.name=name;
this.age=age;
}
Mianmian.prototype={
sum:function(a,b) {
return a+b;
},
divide:function(a,b) {
return a/b;
}
};
var mianmian=new Mianmian("xiaomian",19);
delete(Mianmian.prototype.sum); //刪除原型屬性
console.log(mianmian.sum) //undefined奔穿,,繼承對象的屬性隨之改變
檢測屬性
in
:如果對象的自有屬性或繼承屬性中包含這個屬性就返回true
var o={x:1};
"x" in o; //true
"toString" in o; //true
hasOwnproperty
:檢測給定名字是否為對象的自有屬性敏晤,對于繼承屬性返回false
propertyIsEnumerable
:檢測是自有屬性并且這個屬性可枚舉時才返回true
還有一個是贱田!==
判斷一個屬性是否為undefined,如果為undefined的話就返回false嘴脾,這樣的話使用跟in
有點相似男摧,但是呢蔬墩,如果一個對象的值為undefined的話就會出現(xiàn)差異。
var m={a:undefined};
console.log(m.a in m); //false
console.log("a" in m); //true
console.log(m.a!==undefined); //false
console.log("a"!==undefined) //true
枚舉屬性
for/in 循環(huán)可在循環(huán)中遍歷對象中可枚舉的屬性耗拓,包括自有屬性和繼承屬性拇颅。對象中的內(nèi)置方法是不可枚舉的,但在代碼中添加的屬性是可枚舉的乔询。為了避免枚舉一些不可用參數(shù)樟插,可以用
var m={x:2,y:{a:1,b:2}};
for(var p in m)
{
if(!m.hasOwnProperty(p)||typeof m[p]==="function")continue; //除去繼承屬性和方法
console.log(p);
}
屬性getter和setter
不是很會。待補充
屬性的特性:
value竿刁,writable(可寫性)黄锤,enumerable(可枚舉性),configurable(可配置性)
要想設(shè)置屬性的特性们妥,或者想讓新建屬性具有某種特性,需要調(diào)用Object.defineproperty(),傳入要修改的對象勉吻,要創(chuàng)建或修改的屬性名稱以及屬性描述符對象
var o={};
Object.defineProperty(o,"x",{value:1
writable:true,
enumerable:false,
configurable:true});
console.log(o.x); //1
Object.defineProperty(o,"x",{writable:false});
o.x=2; //操作失敗
console.log(o.x); //1
可配置的意思就是你還可以通過以下的方式改變值
Object.defineProperty(o,"x",{value:2});
console.log(o.x); //2
如果不可配置的話就會是這樣
var p=Object.defineProperties({},{
x:{value:1,writable:false,enumerable:true,configurable:false},
y:{value:8,writable:false,enumerable:true,configurable:true}
});
Object.defineProperty(p,"x",{value:8}); //報錯
對于新創(chuàng)建的屬性來說监婶,默認(rèn)的特性值是false或undefined,這個方法要么修改已有屬性要么新建自有屬性齿桃,但不會改變繼承屬性惑惶。
通過Object.defineProperties()可同時修改或創(chuàng)建多個屬性,就像包含多個小對象一樣短纵,如:
var p=Object.defineProperties({},{
x:{value:1,writable:true,enumerable:true,configurable:true},
y:{value:8,writable:false,enumerable:true,configurable:true}
});
p.x=9
console.log(p.x); //9
p.y=3;
console.log(p.y) //8
可拓展性
一般來說带污,所有的內(nèi)置對象和自定義對象都是可拓展的,但是可以通過Object.preventExtensions()
和Object.seal()
將其設(shè)置為不可拓展的香到,但是一旦轉(zhuǎn)為不可拓展就不能再轉(zhuǎn)換為可拓展的了鱼冀,Object.esExtensible()
檢測對象是否可拓展,seal()
檢測對象是否封閉
比較:
1 .
var o={x:1,y:3};
Object.seal(o);
o.a=1;
console.log(Object.isSealed(o)); //true
2 .
var o={x:1,y:3};
Object.preventExtensions(o);
o.x=2; //2
console.log(Object.isExtensible(o)); //false
3 .
var o={x:1,y:3};
Object.seal(o);
o.a=1;
console.log(Object.isExtensible(o)); // false
4 .
var o={x:1,y:3};
Object.preventExtensions(o);
o.a=1;
console.log(Object.isSealed(o)); //false
這說明Object.seal()
是比Object.preventExtensions()
更嚴(yán)格的鎖定對象悠就,并且他們都可以修改原先屬性中的值千绪,暫時還沒了解到其中的區(qū)別,另外還有一個Object.freeze()
函數(shù)則是更更嚴(yán)格的鎖定對象,他連屬性中的值都不能改變