闭包的漏洞
1. 闭包的定义
- 闭包就是能够读取其他函数内部变量的函数。在JavaScript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。本质上,闭包是将函数内部和函数外部连接起来的桥梁。
2. 构成闭包的条件
- 在函数A内部直接或间接返回一个函数B
- 函数B内部使用函数A的私有变量
- 函数A外部有一个变量接收函数B
下面是一个典型的闭包场景
function a(){
var num = 100
return (function b(){
console.log(num);
})()
}
a() // 100
3. 闭包的漏洞
- 定义:在不改变闭包的情况下修改闭包里面的私有变量
下面是一个闭包漏洞的例子
var o = (function (){
var obj = {
a: 1,
b: 2,
}
return{
get: function(k){
return obj[k]
}
}
})()
下面是闭包漏洞的实现方法
// 在全局Object对象中添加add属性,返回的是this
// 作用是返回当前调用Object对象原型链add属性的对象
Object.defineProperty(Object.prototype, 'add', {
get(){
return this
}
})
console.log(o.get('add')); // { a: 1, b: 2 }
// o.get('add')即可获取obj对象
// 原理是obj对象读取Object对象原型链上的add属性
o.get('add').a = '海绵宝宝' // 修改obj对象的a属性
// 验证a属性被修改成功
console.log(o.get('a')); // 派大星
4. 闭包的漏洞防止方法
4.1 判断法
var o = (function (){
var obj = {
a: 1,
b: 2,
}
return{
get: function(k){
// 判断obj对象是否有属于它对应的属性
if(obj.hasOwnProperty(k)){
return obj[k]
}
// 不是obj对象本身的属性就返回undefined
return undefined
}
}
})()
4.2 置空法
var o = (function (){
var obj = {
a: 1,
b: 2,
}
// 把obj对象在Object原型链上置为null
Object.setPrototypeOf(obj, null)
return{
get: function(k){
return obj[k]
}
}
})()