JavaScript高级程序设计(第3版)学习笔记10 再访(3)

保护级别   描述   操作方法   判断方法   说明  
不可扩展   不能给对象添加新属性和方法,但可以修改已有属性和方法   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__直接访问,来验证一下:

复制代码 代码如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wddsdz.html