-
私有属性要求:
- 不能被外界访问到
- 不能被多个实例共享
用闭包实现私有变量
const creatingFn = (function () {
let data//被保存的数据
class InsideClass {
constructor(val) {
data = val//捆绑作用域外参数
}
getDate() {
return data
}
}
return InsideClass
})()//立刻执行函数
console.log(new creatingFn(1).getDate())//1
console.log(new creatingFn(2).getDate())//2
console.log(new creatingFn(3).getDate())//3
用symbol加闭包实现私有变量
//用闭包加symbol实现私有变量
const creatingFn = (function () {
let data = Symbol('data')
class InsideClass {
constructor(val) {
this[data] = val
}
getData() {
return this[data]
}
}
return InsideClass
})()
let fn1 = new creatingFn(1)
console.log(fn1.getData())//1
let fn2 = new creatingFn(2)
console.log(fn2.getData())//2
let fn3 = new creatingFn(3)
console.log(fn3.getData())//3
console.log(fn3[Object.getOwnPropertySymbols(fn3)[0]])//Symbol反而坏事了
⚠️ 可以被其他的方法访问,就不私有了
用weakMap实现私有变量
思路就是将私有变量的值作为弱映射的值,不知道键的时候就无法访问,键是对象实例
const creatingFn = (function () {
let data = new WeakMap()
class InsideClass {
constructor(val) {
data.set(this, val)
}
getData() {
return data.get(this)
}
}
return InsideClass
})()
let fn1 = new creatingFn(1)
let fn2 = new creatingFn(2)
let fn3 = new creatingFn(3)
console.log(fn1.getData(), fn2.getData(), fn3.getData())
升级版 闭包 WeakMap 私有变量 集
//升级版weakMap闭包私有函数
//在privateDataMap里面值是privateDataSet,privateData也是键值对键叫property,对应的privateDate就是我们要存储的私有变量
const SuperPrivate = (() => {
let privateDateMap = new WeakMap()//不是只有一个私有变量,每一个实例都可以保存很多个私有变量
class Private {
constructor(id) {//创建的时候有一个id,这个id也必须是私有函数
this.idProperty = Symbol("initialId")//这是我们这个实例创建的id的键
this.setProperty(this.idProperty, id)
}
setProperty(property, privateData) {
//注意这里一开始是没有键的,第一次是要创建的,我们用一个断言
const privateDataSet = privateDateMap.get(this) || {}
privateDataSet[property] = privateData//推入privataData到privateDataSet中
console.log(privateDataSet)
privateDateMap.set(this, privateDataSet)//保存到weakmap中
}
getProperty(property) {
return privateDateMap.get(this)[property]
}
getId() {
return this.getProperty(this.idProperty)
}
}
return Private
}
)()
let testing1 = new SuperPrivate(123)
console.log(testing1.getId())
testing1.setProperty('password', 456)
console.log(testing1.getProperty('password'))
//如果不是闭包的话可以这样访问
privateMap.get(testing1)[testing1.idProperty]
privateMap.get(testing1)[property]
//那就不妙了