在实际应用中,有需要用到私有属性的应用场景,但是在JavaScript中,有像java那样的私有属性修饰符吗?当然没有!
那只能利用其它方式去实现“私有属性了”。
从ES3起,就有实现私有属性的方式,实现的代码如下:
{
//ES3
var Pet = function () {
var pet = {
name:'小白ES3',
type:'dog',
age:10
}
this.set = function(key,val){
if(key==='type') return
pet[key] = val
}
this.get = function(key){
return pet[key]
}
}
var pet = new Pet()
console.table({
name:pet.get('name'),
type:pet.get('type'),
age:pet.get('age'),
})
pet.set('age',11)
pet.set('type','cat')
console.table({
name:pet.get('name'),
type:pet.get('type'),
age:pet.get('age'),
})
}
但是,通过ES3实现的“私有属性”,无论是访问(get)还是设置(set),都要利用其暴露在外的方法,并不方便日常的coding;有没有办法通过点语法去访问和设置呢?请继续往下看!
到了ES5,利用Object.defineProperty,实现的方式进一步改变:
{
//ES5
var pet = {
name:'小白ES5',
age:10
}
Object.defineProperty(pet,'type',{
writable:false,
value:'dog'
})
console.table({
name:pet.name,
type:pet.type,
age:pet.age,
})
pet.age = 12
try{
pet.type = 'cat'
}catch(e){
console.log(e)//在这里打印了由于给type设值抛出的错误
}
console.table({
name:pet.name,
type:pet.type,
age:pet.age,
})
}
虽然这种通过ES5实现的私有属性,可以直接用点的语法去get和set(更多Object.defineProperty用法可以点这里https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty),
但是,当私有的属性有一定的数量时....难道要一个个地用Object.defineProperty去把属性保护起来吗?我选择拒绝!
到了ES6,出现了一个Proxy(代理),可以用于拦截和代理去处理一些事情(get、set、...等等),实现私有属性的方式如下:
{
//ES6
let pet = new Proxy(
{
name:'小白ES6',
type:'dog',
age:10
},
{
get(target,key){
return target[key]
},
set(target,key,val){
if(key!=='type'){
target[key] = val
return true
}
return false
}
})
console.table(pet)
pet.age = 12
try{
pet.type = 'cat'
}catch(e){
console.log(e)//在这里打印了由于给type设值抛出的错误
}
console.table(pet)
}
利用Proxy终于可以比较方便地区“保护”一些属性了!
希望将来会有更方便的api,去保护我们想要保护的东西(属性)啦
更多的Proxy的api,可以点这里https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy
网友评论