本文参考:JavaScript权威指南(第六版)
一下几种情况给o设置属性会失败
1、o的属性p是只可读的(defineProperty()方法中有一个例外,可以对配置的只读属性重新赋值)
怎么设置只可读属性了?以下方法可以参考
方法一
var object2 = {
get readOnlyPropery (){
return 1024;
}
}
console.log(object2.readOnlyPropery);
object2.readOnlyPropery = 1000;
console.log(object2.readOnlyPropery);
方法二,如果已经定义好了对象了可以这么做
var myObject = {};
myObject.__defineGetter__("readOnlyProperty", function() { return 1024; })
方法三
var man={};
Object.defineProperty(man,"age",{
value:"21",
writable:false,
enumerable:true,
configurable:true
})
方法四,使用模块只暴露出get,不暴露set
var object = (function(){
var name = "张三";
function getName(){
return name;
}
return {getName:getName};
})();
object.getName();
"张三"
object.name //undefined
方法五:行业有个约定用名字全大写来表示常量(只可读),有时候约定也是解决事情的办法
var NAME = "张三"
2、o的属性p属性是继承的、且只可读的
3、o中不存在的自有属性p。o中没有使用setter方法继承属性p,且o的可扩展性(extensible attribute)是false,如果o中不存在属性p,且不存在se'tter方法可以调用,则p一定会添加到o中,但o是不可扩展的,o中不能定义新属性
二、属性的删除
使用delete表达式删除属性(一般都是属性访问表达式,非严格模式下的全局对象的属性除外)。这里的删除只是断开属性可宿主环境的联系,并没有操作属性本身。
注:属性访问表达式的形式:1、a.b 2、a[b]
var man = {nam:"张三"}
Object.defineProperty(man,"age",{
value:"21",
writable:true,
enumerable:true,
configurable:false
})
delete Object.prototype //false
delete man.age; //false 不可配置的参数,严格模式会报错
delete man.nam; //true 也可以写成 delete man["name"]
function f(){};
delete this.f //false 全局函数和全局变量不能删除
this.g = function (){};
delete g; //true 此时可以删除全局对象,但严格模式会报错
delete 1 //true 没意义
三、属性的检测
属性的检测可以用in、hasOwnProperty()、propertyIsEunmerable()检测
1、in
var s={x:"1"};
"x" in s; //true
"y" in s; //false
"toString" in s; //true 通过原型链继承而来
hasOwnProperty()//判断对象自有的属性,非继承而来
propertyIsEunmerable() //判断是自由属性并且是可枚举的,是hasOwnProperty的增强版
var man={};
Object.defineProperty(man,"age",{
value:2,
enumerable:false
})
man.propertyIsEnumerable("age"); //false
四、总结
说了js对象的属性的设置、删除和检测,注意es5里利用
Object.defineProperty(man,"age",{
value:"21",
writable:false, //是否可惜
enumerable:true, //是否可枚举
configurable:true //是否可配置
})
还有就是约定俗成也是解决问题的办法