1分钟学会如何用 JS 对象代理(proxies)实现对象的私有属性

前端历劫之路

共 2041字,需浏览 5分钟

 ·

2021-11-13 17:48


今天我们来聊聊私有属性,在其他的高级语言中很容易能实现私有属性的功能,那么在 JS 中怎么实现对象的私有属性呢,首先我们聊聊私有属性运用的需求场景,比如我们在对象里用 _ 符号开头的形式定义对象的私有属性,不希望外部环境读取私有属性,如下段代码所示

let bankAccount = {
    holderName'Joe',
    currency'USD',
    _balance1000
}

我们希望读取对象  _balance 的私有属性或删除对象的 _balance 属性,会有如下的提示:

// don't allow reading the balance
console.log(bankAccount._balance);
// don't allow deleting the property
delete _balance

那我们该如何实现呢?这时候我们可以使用 JS 代理,针对 _符号开头的私有属性进行特殊的逻辑处理(你也可以用其他的符号自定义私有属性),废话不多说,上代理的实现的代码逻辑,以下为代理拦截器方法的代码:

let proxyHandler = { 
    has(target, prop) => { 
        if(prop.startsWith(prefix)){ 
            return false;
        } 
        return prop in target 
    }, // 针对 in 方法的重写
    ownKeystarget => { 
        return Reflect.ownKeys(target).filter( 
            prop => !prop.startsWith(prefix) 
        ) 
    }, //针对 keys 方法的重写
    get(target, prop) => { 
        if(prop.startsWith(prefix)) { 
            return undefined
        } 
        return target[prop]; 
    }, 
    deleteProperty(target, prop) { 
        if (prop.startsWith('_')) { 
            return true//私有属性不删除
        } else { 
            delete target[prop]; 
            return true
        }
    }
}

接下来,我们来验证下上述代码是否可行:

const hidePrivateFields = (target, prefix = "_") => { 
    return new Proxy(target, proxyHandler)
};

let bankAccount = hidePrivateFields({
    holderName'Joe',
    currency'USD',
    _balance1000
})

console.log(bankAccount._balance) // undefined 
console.log('_balance' in bankAccount) //false
console.log(Object.keys(bankAccount)) // ['holderName', 'currency'] 
console.log(delete bankAccount._balance) // returns true, but does not delete the balance

今天关于 JS 对象代理在私有属性方面的应用就分享到这里,下一篇文章,我们将继续分享代理有趣的应用,比如以前JQ 插件库可以通过链式语法很容易的操控样式,如下所示,如果让你用 JS 对象代理,你会如何实现呢?

style(".menu").color("#fff").backgroundColor("#000").opacity("1");

文章来源:http://www.js-craft.io/blog/javascript-proxies-restricting-access-to-object-properties-and-some-other-practical-examples/   

作者:Daniel


点击卡片,关注我吧~

浏览 32
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报