js中对象的属性特性(property attribute)和存取器特性(accessor attribute)的思考

最近在狂补js的底层知识,在对象这一块,基本所有书都用了一定的篇幅去介绍属性特性和存取器特性

4种属性特性

value, writable,enumerable, configurable

4种存取器特性

get set enumerable, configurable

那问题来了,这些东西在实际开发中有什么用呢

感觉如果涉及到自己编写框架,可能会用这写功能去做一些限制,但如果是其他用途,很难想到什么需要去diy这些属性的地方,所以还想请大佬们指教

另,ES6里已经有了proxy,那getter和setter还有什么用武之地吗

阅读 2.8k
3 个回答
  1. 有什么用。
    我实际开发中很少用这几个属性,但是并不意外着没用。es 提供属性特性,可以使对象操作的时候有更多的配置性。比如设置不可枚举,不可改变,不可删除的属性。当你遇到真实的场景,自然会派上用场。大可不必太纠结它在工作中的用场。
  2. get,set 跟 proxy 的理念是不同的。get, set 在面向对象编程中是比较重要的,算是提供了属 性的接口,而上述的属性则提供了属性访问的安全性。这个在其他,比如 c 语言中都是有的,算是 js 丰富自己的语言的严谨性。get,set 的用处很多,比如 vue,mobx 就用它处理了依赖收集,这个我就不必多说了,都是源码解析。

    proxy 则是类似于元编程的思想,什么是元编程?知乎看一下怎么理解元编程?。也就是说 proxy 可以做很多 get,set 做不了的事情,初衷以及维度、高度是不同的。比如 get 只能知道对象属性被访问了,却不能收到任何的参数。

我是来围观的,因为我也不懂这几个东西,我只知道有些时候不希望循环遍历到某个属性(不属于这个对象或不应该被遍历到)的时候,就会用到enumerable;

var arr = {}
Object.defineProperty(arr, "length", {
    get: function () {
        let n = 0;
        for (i in this) {
            n++;
        }
        return n;
    },
    enumerable: false, // 设置为不可枚举
    configurable: false // 设置为不可配置
})

console.log(arr.length); // 0,length不可枚举,getter里的for循环会跳过length这个属性

arr.length = 1;
console.log(arr.length); // 0,length不可写

arr[0] = 1;
console.log(arr.length); // 1

Object.defineProperty(arr, "length", { enumerable: true })
// 报错,length不可配置
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题