资讯专栏INFORMATION COLUMN

深入浅出JS的对象属性

Carl / 1869人阅读

摘要:布尔值,是否能通过循环或返回属性。而区别在于为布尔值的特征的默认值,通过属性访问器设置的默认都是,而通过定义属性设置的默认都是。该方法返回被冻结的对象。

可能很多人都知道最近很火的MVVM(model-view-virtualModel)框架,如Vue/Angular/React,如果你不知道的话,就要抓紧学习了,它能够把你从高频复杂的DOM解析中解脱出来。
MVVM框架的最主要的特性就是双向数据绑定,其中使用了ES5的getter/setter函数,而他们就是对象的访问器属性,如果你不清楚它们的具体用法,那就不算是真正了解Javascript的基础知识对象的属性,现在让我们一起回顾和总结下对象的属性。

对象

让我们先看下对象的定义:

无序属性的集合,其属性可以包含基本值,对象或者函数。   ------ ECMA-262

也就是我们可以定义的对象属性只能是下面三种:

var person = {
    // 属性
    name: "Nicholas",
    // 对象
    job: {
        name: "teacher",
        salary: 10000
    },
    // 函数
    greet: function () {
        alert("hello");
    }
};
对象的属性

JavaScript中只包含有两种属性:数据属性和访问器属性,并包含不同的特征。

数据属性包含数据值的位置,可以在该位置对其进行读写。其包含4个特征:

   configurable: 布尔值,表示能否通过delete属性来删除属性或修改属性的特性。
   enumerable: 布尔值,是否能通过`for-in`循环或`Object.keys()`返回属性。
   writable: 布尔值,属性值是否可以修改。
   value: 属性的数据值,实质指向的是读写数据的位置。默认为undefined。

数据属性可以通过属性访问器(即点运算符和方括号计算表达式)来设置属性,也可以通过Object.defineProperty() 或 Object.defineProperties()设置(下面统一用defineProperty代指两者)。而区别在于为布尔值的特征的默认值,通过属性访问器设置的默认都是true,而通过定义属性设置的默认都是false。

访问器属性不包含数据值,包含一对儿getter/setter函数(非必须),在读取访问器属性时,调用getter函数,负责返回有效的值;在写入属性时,调用setter函数并传入新值,负责决定如何处理数据。其包含4个特征:

    configurable: 布尔值,表示能否通过delete属性来删除属性或修改属性的特性,默认为false。
    enumerable: 布尔值,是否能通过`for-in`循环或`Object.keys()`返回属性,默认为false。
    get: 读取属性时调用的函数,默认为undefined。
    set: 写入属性时调用的函数,接收唯一参数,默认为undefined。

访问器属性只能通过defineProperty来定义。

如果属性已经存在,我们可以用defineProperty再次修改该属性的特征,也可以通过Object.getOwnpropertyDescriptor() 或 Object.getOwnpropertyDescriptors()来查看其特征列表。对于configurable = true的属性我们也可以使用delete操作符进行删除,如果设置成了不可配置的,我们就再也不能把它变回可配置的了。

属性访问器

有时我们会通过getter/setter来代理一个属性的读取操作,即实现一个伪属性,但是这个属性不能与真实属性重名,否则会覆盖真实属性的值,变成动态获取,这可能不是你想要的结果。

// 实例:保存当前值变化的日志记录
var o = {
    set current (str) {
        this.log[this.log.length] = str;
    },
    get current () {
        return this.log.join(",");
    },
    log: []
};

这样我们就代理current,用于保存实时日志,每次对log的更新也变成了一个操作历史档案,方便实时查看我们的所有改动。
同样我们可以在configurable配置为true的时候删除该属性的代理:delete o.current

关于delete,如果我们删除了一个var/let/const属性,在其声明的作用域下会返回false,如果是严格模式,则会抛出语法错误。删除一个不可配置的属性同理会失败或报错。
删除数组的下标时,length并不会变小,遍历到该下标时会跳过执行。

影响configurable的方法

另外,存在一些Object的方法会影响到对象属性的可配置性:

Object.freeze()
该方法可以冻结一个对象,冻结指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性、可配置性、可写性。也就是说,这个对象永远是不可变的。该方法返回被冻结的对象。
冻结指的是表层属性的浅冻结,如果需要冻结嵌套的属性,则需要遍历并递归冻结子属性。

Object.preventExtensions()
该方法让一个对象变的不可扩展,也就是永远不能再添加新的属性。需要注意的是不可扩展的对象的属性通常仍然可以被删除,同时会阻止一个对象将__proto__属性重新指向另一个对象。

Object.seal()
该方法可以让一个对象密封,并返回被密封后的对象。密封对象将会阻止向对象添加新的属性,并且会将所有已有属性的可配置性(configurable)置为不可配置(false),即不可修改属性的描述或删除属性。但是可写性描述(writable)为可写(true)的属性的值仍然被修改。

参考资料

MDN - Object: https://developer.mozilla.org...

JavaScript高级编程 - 对象类型

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88697.html

相关文章

  • 深入浅出JS原型链工作原理

    摘要:前言原型链,即原型链条。原型的作用在中,每个对象都有自己的原型。访问的属性方法依旧不存在于该原型,则会继续访问该原型的原型 前言:原型链,即原型链条。它是由原型、原型的原型、原型的原型的原型...这一规则组合成的,经常被应用于继承。 原型的作用在JS中,每个对象都有自己的原型。当我们访问对象的属性和方法时,JS会先访问对象本身的属性和方法。如果对象本身不包含这些属性和方法,则访问对象...

    Ali_ 评论0 收藏0
  • JavaScript深入浅出

    摘要:理解的函数基础要搞好深入浅出原型使用原型模型,虽然这经常被当作缺点提及,但是只要善于运用,其实基于原型的继承模型比传统的类继承还要强大。中文指南基本操作指南二继续熟悉的几对方法,包括,,。商业转载请联系作者获得授权,非商业转载请注明出处。 怎样使用 this 因为本人属于伪前端,因此文中只看懂了 8 成左右,希望能够给大家带来帮助....(据说是阿里的前端妹子写的) this 的值到底...

    blair 评论0 收藏0
  • js基础深入浅出

    摘要:当多个事件触发的时候,会把异步事件依次的放入里等同步事件执行完之后,再去队列里一个个执行拾遗常用方法总结面试的信心来源于过硬的基础参考高级程序设计你所不知道的深入浅出知识点思维导图经典实例总结那些剪不断理还乱的关系 持续不断更新。。。 基本类型和引用类型 vue props | Primitive vs Reference Types 基本类型和字面值之间的区别 基本类型和字面值相等,...

    phodal 评论0 收藏0
  • Javascript 深入浅出原型

    摘要:重点实例对象是通过原型对象与构造函数取得联系的。原型链的形成是真正是靠的,而不是。函数对象和原型对象通过和属性进行相互关联。 JavaScript 使用 prototypal 原型模型,虽然这经常被当作缺点提及,但是只要善于运用,其实基于原型的继承模型比传统的类继承还要强大。 个人博客排版更佳:https://haonancx.github.io/ showImg(https://se...

    wpw 评论0 收藏0
  • 深入学习js之——作用域链

    摘要:开篇作用域是每种计算机语言最重要的基础之一,因此要想深入的学习作用域和作用域链就是个绕不开的话题。这样由多个执行上下文的变量对象构成的链表就叫做作用域链。这时候执行上下文的作用域链,我们命名为至此,作用域链创建完毕。 开篇 作用域是每种计算机语言最重要的基础之一,因此要想深入的学习JavaScript,作用域和作用域链就是个绕不开的话题。 在《深入学习js之—-执行上下文栈》中我们提到...

    lemanli 评论0 收藏0

发表评论

0条评论

Carl

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<