原型
創建新對象
Object.create(Object.prototype)
;
屬性查詢和設置
通過"."或方括號來獲取屬性的值,值得注意的是使用方括號時里面的值是以屬性命名的字符串,用方括號有點類似于數組。
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;
發現什么 了沒有,就是在查找繼承的時候是從下往上一層一層的查找原型的,當找到x時即返回值,停止。對象的原型屬性就像一個“鏈”,這個鏈實現 屬性的繼承。
在js中,只有在查詢屬性的時候才會體會到繼承的存在,而設置屬性與繼承無關無法通過繼承的屬性值的改變來改變原型的值;
var o={};
o.x=3;
var m=inherit(o);
function inherit(p) { //繼承函數
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的話就會出現差異。
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 循環可在循環中遍歷對象中可枚舉的屬性,包括自有屬性和繼承屬性。對象中的內置方法是不可枚舉的,但在代碼中添加的屬性是可枚舉的。為了避免枚舉一些不可用參數,可以用
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(可配置性)
要想設置屬性的特性,或者想讓新建屬性具有某種特性,需要調用Object.defineproperty(),傳入要修改的對象,要創建或修改的屬性名稱以及屬性描述符對象
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}); //報錯
對于新創建的屬性來說,默認的特性值是false或undefined,這個方法要么修改已有屬性要么新建自有屬性,但不會改變繼承屬性。
通過Object.defineProperties()可同時修改或創建多個屬性,就像包含多個小對象一樣,如:
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
可拓展性
一般來說,所有的內置對象和自定義對象都是可拓展的,但是可以通過Object.preventExtensions()
和Object.seal()
將其設置為不可拓展的,但是一旦轉為不可拓展就不能再轉換為可拓展的了,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()
更嚴格的鎖定對象,并且他們都可以修改原先屬性中的值,暫時還沒了解到其中的區別,另外還有一個Object.freeze()
函數則是更更嚴格的鎖定對象,他連屬性中的值都不能改變