003 理解对象

作者: 柏丘君 | 来源:发表于2017-08-09 21:01 被阅读2次

在 JavaScript 中,每个对象都是基于另一个对象创建的,也叫做对象的原型。所有对象都是通过其原型对象创建出来的。
不同的对象都有各自的属性,ECMAScript 中有两种类型的属性:数据属性访问器属性
数据属性,就是最常见的有实实在在的值的属性,访问器属性则是那些通过 gettersetter 函数进行访问和赋值的属性。对于这两种属性,都有描述各自行为的特性。首先来看数据属性。

数据属性

数据属性有以下几个描述其行为的特性:

  • [[Configurable]]:此描述符表示是否能够删除该属性,默认为 true
  • [[Enumerable]]:此描述符表示该属性是否可以通过 for-in 循环枚举,默认为 true
  • [[Writable]]:此描述符表示该属性是否可写,默认为 true
  • [[Value]]:此描述符专门用来保存该属性的值,读取属性时,从这个位置读取,写入属性时(如果该属性可写的情况下),就写入在这个位置。该描述符的默认值为 undefined

访问器属性

访问器属性不包含具体的属性值,其包含了一对 gettersetter 函数(非必须),在读取属性值时,将调用 getter 函数,将此函数的返回值作为读取的值。在设置属性时,将调用 setter 函数,在该函数中完成对属性值的设置。
访问器属性有以下几个描述其行为的特性:

  • [[Configurable]]:同上
  • [[Enumerable]]:同上
  • [[Get]]:读取属性时调用的函数,默认值为 undefined
  • [[Set]]:设置属性时调用的函数,默认值为 undefined

访问器属性不能直接定义,必须通过 Object.defineProperty() 来进行定义。

Object.defineProperty() 方法

该方法用来对属性进行配置,包括数据属性和访问器属性。该函数接受三个参数:

  • 属性所在的对象
  • 属性名
  • 属性描述符对象

调用该方法返回被定义后的对象。
1.定义数据属性

let ball = {name:"basketball",brand:"NIKE"};
Object.defineProperty(ball,"name",{
    writable:false
}); //{name:"basketball",brand:"NIKE"}
ball.name = "pingpang";
ball.name //"basketball";

2.定义访问器属性

let ball = {}
Object.defineProperty(ball,"name",{
    get:function(){
        return this._name
    },
    set:function(name){
        this._name = name
    }
})
ball.name //undefined
ball.name = "篮球"
ball.name //"篮球"
ball._name //"篮球"
ball._name = "足球"
ball.name //"篮球"

getter 函数中,我们访问 name 属性时返回当前对象的 _name 属性,在 setter 函数中,我们设置 name 的值时会设置设置该对象的 _name 属性,也就是 name 属性的值始终依赖于 _name 属性的值,而当我们修改 _name 属性的值后,获取到的 name 属性的值也相应变化了。

关于 [[Configurable]] 描述符

一旦将 [[Configurable]] 设置为 false 后,该属性就变成了“不可配置”状态,此时,除了对 [[Writable]] 描述符进行配置外,进行其他的配置都会报错。

let ball = {}
Object.defineProperty(ball,"name",{
    configurable:false,
    value:"篮球"
})
// 再次配置
Object.defineProperty(ball,"name",{
    configurable:true,
})

此时会产生错误:

VM3119:1 Uncaught TypeError: Cannot redefine property: name

但是我们仍然可以对 [[Writable]] 描述符进行配置:

Object.defineProperty(ball,"name",{
    writable:false,
})
ball.name = "足球"
ball.name //"篮球"

定义多个属性

ES5 还提供了定义多个属性的方法:Object.defineProperties(),该方法接受两个参数,第一个参数是配置属性的对象,第二个参数是一个针对待配置属性的描述字典:

let ball = {}
Object.defineProperties(ball,{
    name:{
        writable:false
    },
    brand:{
        configurable:false
    }
})

获取属性特性

通过 Object.getOwnPropertyDescriptor() 方法,可以获取对象的属性的描述符。该方法接受两个参数:属性所在的对象和属性名。

let ball = {}
Object.defineProperties(ball,{
    name:{
        writable:false
    },
    brand:{
        configurable:false
    }
})
Object.getOwnPropertyDescriptor(ball,"name") //{value: undefined, writable: false, enumerable: false, configurable: false}

另外,还有一个 Object.getOwnPropertyDescriptors()方法,可以获取对象上所有的属性特性,该方法只接受一个对象作为参数,返回该对象所有的属性描述符:

Object.getOwnPropertyDescriptors(ball)

返回值:

{
brand: {value: undefined, writable: false, enumerable: false, configurable: false},
name: {value: undefined, writable: false, enumerable: false, configurable: false}
}

完。

相关文章

  • 003 理解对象

    在 JavaScript 中,每个对象都是基于另一个对象创建的,也叫做对象的原型。所有对象都是通过其原型对象创建出...

  • 0x003 理解iOS weak对象存储原理

    理解iOS weak对象存储原理 1、案例代码 分别声明__weak弱引用对象obj、obj1 2、分析__wea...

  • 面向对象--理解对象

    面向对象(Object-Oriented OO)的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意多...

  • 面向对象—理解对象

    什么是对象? 我们可以把ECMAScript的对象想象成散列表,也就是一组名值对,其中值可以是数据和函数。 对象的...

  • 004--OC对象原理探究 - isa走位及对象继承链

    引言 接上篇文章003-OC对象原理探究 - isa 和 nonpointer[https://www.jians...

  • case

    001 002 003 004 005编码问题 006 007默写尽可能多的str对象的方法 008

  • Javascript对象

    对象 在JavaScript里几乎所有东西都是对象或者用起来像对象,理解了对象就能够理解JavaScript。对象...

  • day5(12.20) 面向对象的程序设计

    理解对象的属性 理解并创建对象 理解继承 对象的属性 ECMAScript中的对象:一组名值对,其中值可以是数据或...

  • 003-OC对象本质

    oc是面向对象的语言。对象可以看做我们对底层数据的抽象封装。对象有自己的成员变量,具备一些功能,有自己所属的类,甚...

  • javascript高级程序设计(第6章)-- 面向对象的程序设

    第六章:面向对象的程序设计 本章内容: 理解对象属性 理解并创建对象 理解继承 ECMA-262把对象定义为:"无...

网友评论

    本文标题:003 理解对象

    本文链接:https://www.haomeiwen.com/subject/ndiqrxtx.html