保护级别
描述
操作方法
判断方法
说明
不可扩展
不能给对象添加新属性和方法,但可以修改已有属性和方法
preventExtensions()
isExtensible():不能扩展时返回false
密封
不可扩展,并且已有成员的[[Configurable]]设置为false,不能删除属性,但可以修改属性值
seal()
isSeal():被密封时返回true
isSeal()为true时一定有isExtensible()为false
冻结
密封,其[[Writable]]设置为false,但如果定义了[[Set]],访问器属性仍然可写
freeze()
isFrozen():被冻结时返回true
isFrozen()为true时一定有isSeal()为true,isExtensible()为false
注:一旦定义成了防篡改对象,就不能撤销。
(3)对象的其它方法
名称
描述
create(prototype[,descriptors])
创建一个具有指定原型且可选择性地包含指定属性的对象
getOwnPropertyNames(object)
返回对象的属性(方法)的名称
getPrototypeOf(object)
返回对象的原型
keys(object)
返回对象的可枚举属性(方法)的名称
这里的create(prototype[,descriptors])是一个非常有意思的方法,规范中这样描述它的行为:
[code]
①如果prototype不是Null或Object,抛出TypeError异常
②var obj = new Object()
③设置obj的内部属性[[Prototype]]为prototype
④如果descriptors存在且不为undefined,使用Object.defineProperties(obj,descriptors)来添加属性
⑤返回obj
由于一般对象的[[Prototype]]不能直接访问,可以使用函数来进行下面模拟实现:
复制代码 代码如下:
(function(){
function Base(){};
Object.create = function(prototype, descriptors){
var typeVal = typeof prototype;
if(typeVal !== null && typeVal !== 'object' && typeVal !== 'function'){
throw new TypeError('类型错误,请检查第一个参数的类型');
}
Base.prototype = prototype;
var result = new Base();
if(descriptors){
Object.defineProperties(result, descriptors);
}
return result;
};
})();
测试一下:
复制代码 代码如下:
try{
var one = Object.create(1);//异常
}catch(e){
console.info(e);//TypeError
}
var base = {
name:'linjisong',
getName:function(){
return this.name;
}
};
var two = Object.create(base);
console.info(two.name);//linjisong
console.info(two.getName());//linjisong
var three = Object.create(base, {
name:{value:'oulinhai'},
age:{value:23}
});
console.info(three.getName());//oulinhai
console.info(three.age);//23
这里实现了一个简单的继承,这也引出下一个主题。
2、原型对象
(1)原型与原型链
每个对象都有一个原型对象,而原型对象本身也是一个对象,也有自己的原型对象,这样就形成了一个原型链直至null对象。对象的内部属性[[Prototype]]指向的就是对象的原型对象,而Object.prototype的原型对象为null。
(2)属性查找
在访问一个对象的属性(方法)时,引擎会先查找对象本身有没有这个属性,如果有,返回这个属性值,如果没有,则查找对象的原型是否有这个属性,如果有,返回,如果没有就继续查找原型对象的原型直至最后一个原型对象。
注意区分属性查找和和前面说过的标识符查找的异同。属性查找是沿着原型链,标识符查找是沿着作用域链,但都有一个逐级查找的过程。
(3)对象的原型对象[[Prototype]]与函数的原型属性prototype
•每一个对象都有一个原型对象,在规范中使用[[Prototype]]来表示,这个对象一般不能直接访问,但可以通过getPrototypeOf()这个方法来获取,而在Firefox中还可以通过__proto__直接访问,来验证一下:
复制代码 代码如下: