一、问题出现
最近在若依框架项目(vue3版本)中发现了一个源码的问题,因此记录下来。
在点击换肤功能时,如下图:
问题:没反应, 并且报错栈满。
最后排查原因发现,在设置点击事件中都同样调用了settingStore.changeSetting这个方法:
然后发现这个方法是在store当中的:
我们试着去理解这个方法,可以打印一下传进来的data是长啥样的,如下图:
方法里面的逻辑就是去检查,传进来的对象的key的值是否在state里面定义了,如果存在就修改state对象里面的值为data.value的值,不存在的话就不执行。
所以,就能够发现问题所在就在于这个判断条件hasOwnProperty:导致栈满。
console.log('this.hasOwnProperty(key)', this.hasOwnProperty(key)); //报错
所以,我们就有正当理由怀疑hasOwnProperty这个方法的性能啦!
二、学习问题
1,JS中的hasOwnProperty是干啥用的?
obj.hasOwnProperty("属性名");
此方法用来判断某个对象是否含有指定的自身属性(而不是原型链上的属性),是则返回true,不是则返回false。
2,用法
hasOwnProperty() 方法是 Object 的原型方法(也称实例方法),它定义在 Object.prototype 对象之上,所有 Object 的实例对象都会继承 hasOwnProperty() 方法。
- 简单运用:
let obj = {
name:'张三',
age:18,
sex:'male',
eat:{
food:'鸡腿',
drink:'water'
}
}
console.log(obj.hasOwnProperty('name')) // true
console.log(obj.hasOwnProperty('age')) //true
console.log(obj.hasOwnProperty('sex')) //true
console.log(obj.hasOwnProperty('eat')) // true
console.log(obj.eat.hasOwnProperty('food')) // true
console.log(obj.eat.hasOwnProperty('drink')) // true
- 搭配for in使用:
for (const key in object) {
if (Object.hasOwnProperty.call(object, key)) {
const element = object[key];
}
}
遍历对象属性时,使用hasOwnProperty检查属性的方法仅处理对象自身的属性,而直接使用for in循环的方法会同时处理对象自身的属性和从原型链中继承的属性。
在实际应用中,如果你只关心对象自身的属性,而不希望处理原型链上的属性,那么就可以用for in搭配hasOwnProperty检查。但是如果你需要同时处理对象自身和原型链上的属性,那么可以直接使用for in。
3,可能问题
- ESLint报错
新版本的ESLint中禁止直接调用Object.proptotype的内置属性开关,说白了就是新版本的不允许这个使用规则了;有可能会报下面这个错:
"Do not access Object.prototype method 'hasOwnProperty' from target object no-prototype-b"
- Web服务器
Object.prototype从而可能导致意外行为或拒绝服务安全漏洞。例如,对于Web服务器来说,解析来自客户端的JSON输入并hasOwnProperty直接调用生成的对象是不安全的,因为恶意客户端可能会发送JSON值,例如,{“hasOwnProperty”: 1}并导致服务器崩溃。
4,解决方法
- Object.prototype.hasOwnProperty.call()
使用原型链上真正的 hasOwnProperty 方法去查找;
- Object.keys().includes()
es6新增方法去查找也是可行的;
三、问题解决
因此原来若依框架报错的问题也就可以解决了,大功告成!