1. ? 位置应该怎么写才能输出true
var a= ? ;
console.log(a==1 && a==2 && a==3)
对象会被转为原始类型 先调用valueOf 然后调用toString
var obj={} // {}
var obj={
num:1,
valueOf:function(){
return this.num++
}
}
2. 闭包的一个漏洞
正如代码,一个闭包 ,保护obj不被污染,但是也会有一个漏洞
var o = (function () {
var obj = {
a: 1,
b: 2
};
return {
get: function (k) {
return obj[k]
}
}
})()
console.log(o.get('b')) // 2
**在访问该属性的时候,等同于调用函数,就不得不提到了访问器属性,通过 defineProperty的get属性可以实现,这样就获取到保护的原对象了,此时可以随意修改,是一个大的漏洞 **
Object.defineProperty(Object.prototype, 'abc', {
get() {
return this
}
})
console.log(o.get('abc')) //{ a: 1,b: 2}
改进方法一
var o = (function () {
var obj = {
a: 1,
b: 2
};
return {
get: function (k) {
if (obj.hasOwnProperty.call('a')) {
// 由于ESLint升级,在项目中直接使用xxx.hasOwnProperty()可能会导致报错;
// 修改方法: Object.prototype.hasOwnProperty.call(obj, 'a')
return obj[k]
}
return undefined
}
}
})()
//在获取属性时,因为hasOwnProperty不会查找对象的原型链所以通过hasOwnProperty可以判断该属性是否存在,如果不存在则返回underfind
改进方法二
var o = (function () {
var obj = {
a: 1,
b: 2
};
Object.setPrototypeOf(obj,nul)
return {
get: function (k) {
return obj[k]
}
}
})()
//上面讲过该函数的漏洞就是利用了原型攻破的,现在把原型置空,就无法攻破了