javascript
1.Object.create(null) 和 {} 的区别
Object.create(null) 创建的是一个干净的空对象,他的原型对象上是空的,而{}可以看作是“不干净”的空对象,因为他能访问到原型对象上的属性和方法,比如hasOwnProperty,toString等等。
为什么要使用Object.create(proto,propertiesObject)?
1.Object.create(null) 可以自定义属性,而不必担心原型链上同名的属性或方法被覆盖。
2.跟{}比起来,在使用for-in遍历属性时候,它会遍历原型对象上的属性,而Object.create(null) 则不会遍历,因此有性能上的优势。
// {} 对象 查找自身属性
let obj1 = {...省略很多属性和方法...}
if(Object.prototype.hasOwnProperty.call(obj1,"toString")){
console.log('yes')
}else{
console.log('no')
}
/***
先确定一下这里对于{}来说,查找自身属性最好的方法是Object.prototype.hasOwnProperty.call,而不是对象自己去调用hasOwnProperty
*/
// 情况一:假如现在要查找obj1对象自身是否含有toString
let obj1 = {
toString:function(){
console.log('自身tostring方法')
},
}
if(Object.prototype.hasOwnProperty.call(obj1,"toString")){
console.log('yes')
}else{
console.log('no')
}
if(obj1.hasOwnProperty("toString")){
console.log('自己调用,yes')
}else{
console.log('自己调用 no')
}
输出: yes
自己调用,yes
//ps:这种情况下,通过Object.prototype.hasOwnProperty.call或者自身调用hasOwnProperty都能正确返回结果。
//但是。。。。。。
//情况二:假如现在obj1对象上定义了一个名叫hasOwnProperty的属性
let obj1 = {
toString:function(){
console.log('自身tostring方法')
},
hasOwnProperty:function (){
console.log("搁着卡bug呢")
}
}
if(Object.prototype.hasOwnProperty.call(obj1,"toString")){
console.log('yes')
}else{
console.log('no')
}
if(obj1.hasOwnProperty("toString")){
console.log('自己调用,yes')
}else{
console.log('自己调用 no')
}
输出: yes
搁着卡bug呢
自己调用 no
// 结果是明明ob1上有toString,obj1.hasOwnProperty("toString")缺判定为假,这是因为obj1自身的hasOwnProperty覆盖了原型对象上的hasOwnProperty方法,因此执行了自身的,并且由于自身的hasOwnProperty方法没有返回值,所以默认返回undefined,即判断的时候走了else条件。解决办法:return true。
// =Object.create(null) 对象 查找自身属性
let obj2=Object.create(null,{
toString:{
writable:true,
configurable:true,
value:function(){
console.log('xixi')
}
}
})
//if(obj2.hasOwnProperty('toString') console.log('没问题') 由于obj2是个干净的对象,obj2.__proto__为undefined,所以不能使用hasOwnProperty
if(obj2.toString()){ //由于没有原型对象,obj2 上有什么自定义的属性就用自己的
console.log('obj2 yes')
}else{
console.log('obj2 no')
}
输出:
xixi
obj2 no //输出no 是因为value 方法没有返回值
总结:
new Object()和字面量形式创建的{} 都是Object的实例,也就是说
obj.__proto__ === Object.prototype // true
obj instanceof Object //true
只不过字面量形式比new Object()高效一点,省去了new的__proto__ 指向和this.
而Object.create(proto, propertiesObject) ,第二个参数可选,它创建出来的对象的__proto__指向传入的原型对象
let obj1=Object.create(null)
obj1.__proto__ // undefined
let obj={a:1}
let obj2=Object.create(obj)
obj2.__proto__ === obj //true
obj2 instanceof Object// true 注意不是obj2 instancof obj
License:
CC BY 4.0