JS 对象属性相关(检查属性、枚举属性等)
1.删除属性
delete运算符可以删除对象的属性
deleteperson.age//即person不再有属性age deleteperson['age']//或者这样
delete只是断开属性和宿主对象的联系,而不会去操作属性中的属性看到deletea.p之后b.x仍然为1
vara={p:{x:1}};
varb=a.p;
console.log(a.p.x);//1
deletea.p;
console.log(a.p.x);//TypeErrora.pisundefined
console.log(a.p);//undefined
console.log(b.x);//1
delete只能删除自有属性,不能删除继承属性(要删除继承属性必须从定义这个属性的原型对象上删除它,当然,这会影响到所有继承来自这个原型的对象)
functioninherit(p){
if(p==null){//不能从null中继承
throwTypeError();
}
if(Object.create){//如果有这个方法就直接使用
returnObject.create(p);
}
vart=typeofp;
if(t!=="object"||t!=="function"){//要继承的对象类型要符合
throwTypeError();
}
functionf(){};//定义一个空的构造函数
f.prototype=p;//原型指向要继承的对象p
returnnewf();//创建f对象,此对象继承自p
}
varobj={x:1};
varobj1=inherit(obj);
obj1.y=2;
console.log("x="+obj1.x+"y="+obj1.y);//x=1y=2
deleteobj1.x;
deleteobj1.y;
console.log("x="+obj1.x+"y="+obj1.y);//x=1y=undefined
当然了,可配置的属性才能用到delete
比如
deleteObject.prototype;//不能删除不可配置
varx=1;
deletethis.x;//不能删除
this.y=1;
deletey;//这样可以删除
functionf(){}
deletethis.f;//不能删除
2.检测属性
使用“in"
in运算符希望它的左操作数是一个字符串或者可以转换为字符串,希望它的右操作数是一个对象
vardata=[5,6,7];
console.log("0"indata);//有下标0
console.log(1indata);//1可以转换成"1"
console.log("4"indata);//下标只有123
varobj={x:1};
console.log("x"inobj);//true
console.log("y"inobj);//false
console.log("toString"inobj);//true因为obj继承了这个方法
使用hasOwnProperty()或者propertyIsEnumerable()---后者是前者的增强
顾明思议
varobj={x:1};
console.log(obj.hasOwnProperty("x"));//true
console.log(obj.hasOwnProperty("y"));//false
console.log(obj.hasOwnProperty("toString"));//false因为obj继承了这个方法,但不是它自己的
只有检测到是自由属性并是可枚举的属性时,后者才返回true
varobj={x:1};
console.log(obj.propertyIsEnumerable("x"));//true
console.log(obj.propertyIsEnumerable("y"));//false
console.log(obj.propertyIsEnumerable("toString"));//false因为obj继承了这个方法,但不是它自己的
console.log(Object.prototype.propertyIsEnumerable("toString"));//false因为最原始的的toString就是不可枚举的
当然,也可以直接用”!=="运算符判断
varobj={x:1};
console.log(obj.x!==undefined);//true
console.log(obj.y!==undefined);//false
console.log(obj.toString!==undefined);//true
3.枚举属性
varobj={x:1,y:2};
for(pinobj){
console.log(p);//xy
console.log(obj.p);//undefinedundefined
console.log(obj[p]);//12
}
拓展1:
每个对象都有与之相关的原型(prototype)、类(class)、可扩展性(extensible)
要检测一个对象是否是另一个对象的原型(或处于原型链中),可以使用isPrototypeOf()方法
varp={x:1};//p原型对象继承自Object.prototype
varo=Object.create(p);//o对象继承自p
console.log(p.isPrototypeOf(o));//true
console.log(Object.prototype.isPrototypeOf(o));//true
console.log(Object.prototype.isPrototypeOf(p));//true
当然,isPrototypeOf()方法和instanceof运算符非常类似
instanceof运算符希望它的左操作数是一个对象,右操作数标识对象的类。如果左侧的对象是右侧类的实例,则表达式返回true,否则返回false
varp={x:1};
console.log(pinstanceofObject);//true
vard=newDate();
console.log(dinstanceofDate);//true
console.log(dinstanceofObject);//true
console.log(dinstanceofNumber);//false
拓展2:
对象的类属性是一个字符串,用以表示对象的类型信息
一般调用toString()方法后返回形如[objectclass]的形式
比如
varobj={x:1,y:2};
console.log(obj.toString());//[objectObject]
所以要想获取对象的类,就可以通过返回的字符串中找出“class"字段 使用slice(8,-1)
比如
functionclassOf(obj){//找出类名
if(obj===null){
return"Null";
}
if(obj===undefined){
return"Undefined";
}
returnObject.prototype.toString.call(obj).slice(8,-1);
}
console.log(classOf(1));//Number
//注意,实际上是这些类型的变量调用toString()方法,而不是通过他们自身直接调用
//console.log(1.toString());//会报错
vara=1;
console.log(Number(1).toString());//1
console.log(a.toString());//1
console.log({x:1}.toString());//[objectObject]
console.log(classOf(1));//Number
console.log(classOf(""));//String
console.log(classOf("str"));//String
console.log(classOf(null));//Null
console.log(classOf(false));//Boolean
console.log(classOf({}));//Object
console.log(classOf([]));//Array
console.log(classOf(newDate()));//Date
functionf(){}
console.log(classOf(newf()));//Object