资讯专栏INFORMATION COLUMN

JavaScript 数据属性和访问器属性

LucasTwilight / 1277人阅读

摘要:数据属性数据属性有个描述其行为的特性表示能否通过删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。在读取访问器属性时,会调用函数,在写入访问器属性时,又会调用函数并传入新值。

JavaScript 数据属性和访问器属性

原文链接

一个例子

先看代码:

var obj = {name:"percy"};
console.log(obj.name);    // percy
obj.name = "zyj";
console.log(obj.name);    // zyj

// 这里借 Math 对象来举例
// 首先说明一下, Math 对象和上面定义的 obj 对象都只是 Object 对象的一个实例
console.log(Math.PI);    // 3.1415926...
Math.PI = 1234;
console.log(Math.PI);    // 3.1415926...

看到了吗?同样是 Object 的实例,obj 对象的属性却可以被改写,而 Math 对象的属性去不能被改写。好,让我们来码一行,从而让 obj 对象的属性也不能被改写:

var obj = {name:"percy"};
console.log(obj.name);    // percy

Object.defineProperty(obj,"name",{writable:false});

obj.name = "zyj";
console.log(obj.name);    // percy

看到了吗,这其中另有玄机,接下来就引入了我们的主角:对象的数据属性访问器属性

为了表示特性是内部值,规范(ECMA-262)就把它们放到了两对儿方括号里了,例如 [[Enumerable]]。

数据属性(Data Properties)

数据属性有4个描述其行为的特性:

[[Configurable]] : 表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。

[[Enumerable]] : 表示能否通过 for-in 循环返回属性。

[[Writable]] : 表示能否修改属性的值。

[[Value]] : 包含这个属性的数据值。读取属性值的时候,从这个位置读;写入属性值时,把新值保存在这个位置。默认值是 undefined。

像这样(var obj = new Object(); obj.name = "percy";)或者像通过对象字面量(var obj = {name: "percy"};)直接在对象上定义的属性,它们的 [[Configurable]]、[[Enumerable]] 和 [[Writable]] 特性默认都被设置为 true,而 [[Value]] 特性被设置为指定的值。

这里注意一下这个(可以先跳过,完了再看):

var person = {};   // 新建一个空对象
Object.defineProperty(person,"name",{
  value: "percy"
});
console.log(Object.getOwnPropertyDescriptor(person,"name"));
// 打印:Object {value: "percy", writable: false, enumerable: false, configurable: false}

没有按上面的2种方法为对象添加属性,而直接通过 Object.defineProperty() 为对象添加属性以及值,这种情况下,这个对象的这个属性的另外3个特性的默认值都是 false。

要修改属性默认的特性,必须使用 ECMAScript 的 Object.defineProperty() 方法。

Object.defineProperty( obj, prop, descriptor)

obj:需要定义属性的对象。

prop:需定义或修改的属性的名字。

descriptor:一个包含设置特性的对象

var person = {name: "percy"};
Object.defineProperty(person,"name",{
  writable: false
});
console.log(person.name);  // percy
person.name = "zyj";
console.log(person.name);  // percy

for(let prop in person){
  console.log(prop + " : " + person[prop]);
}                   // name : percy 
Object.defineProperty(person,"name",{
  enumerable: false
});
for(let prop in person){
  console.log(prop + " : " + person[prop]);
}                   // 什么也没打印

Object.defineProperty(person,"name",{
  configurable: false
});
Object.defineProperty(person,"name",{
  configurable: true
}); // 报错:TypeError: Cannot redefine property: name(…)

// 一旦把属性定义为不可配置的,那么就再也不能把属性定义回可配置的了。
访问器属性(Accessor Properties)

访问器属性不包含数据值,它们包含一对儿 gettersetter 函数(不过,这两个函数都不是必需的)。在读取访问器属性时,会调用 getter 函数,在写入访问器属性时,又会调用 setter 函数并传入新值。

访问器属性有如下4个特性:

[[Configurable]]:表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为数据属性。

[[Enumerable]]:表示能否通过 for-in 循环返回属性。

[[Get]]:在读取属性时调用的函数。默认值为 undefined。

[[Set]]:在写入属性时调用的函数。默认值为 undefined。

访问器属性不能直接定义,必须使用 Object.defineProperty() 来定义。

var book = {
    _year : 2004,
    edition : 1
};
Object.defineProperty(book,"year",{ 
    get : function () {
        alert(this._year);
    },
    set : function (newValue) {
        if (newValue > 2004) {
            this._year = newValue;
            this.edition += newValue - 2004;
        }
    }
});
book.year;      // 弹出窗口,显示 2004
book.year = 2005;
console.log(book.edition);   // 2

要是上面的代码有不懂得地方,参看这里,JavaScript理解对象:属性类型(推荐)

定义多个属性

Object.defineProperties(obj, props)

var obj = {};
Object.defineProperties(obj, {
  "property1": {
    value: true,
    writable: true
  },
  "property2": {
    value: "Hello",
    writable: false
  }
  // 等等.
});

console.log(obj); // Object {property1: true, property2: "Hello"}
读取属性的特性

Object.getOwnPropertyDescriptor(obj, prop) 返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)

var girl = {name: "zyj"};
console.log(Object.getOwnPropertyDescriptor(girl,"name"));
// Object {value: "zyj", writable: true, enumerable: true, configurable: true}

Object.defineProperties(girl,{
  name:{
    writable: false
  },
  age:{
    writable: true,
    value: 22
  }
});

console.log(Object.getOwnPropertyDescriptor(girl,"name"));
// Object {value: "zyj", writable: false, enumerable: true, configurable: true}
console.log(Object.getOwnPropertyDescriptor(girl,"age"));
// Object {value: 22, writable: true, enumerable: false, configurable: false}

var descriptor = Object.getOwnPropertyDescriptor(girl,"age");
console.log(descriptor.value);         // 22
console.log(descriptor.configurable);  // false
console.log(descriptor.writable);      // true
console.log(descriptor.get);           // undefined
console.log(descriptor.set);           // undefined
摘抄自文末的链接

A property is a name (string identifier) associated with a property descriptor.

As of ECMAScript 5, three property types are available:

Internal Properties

Data properties

Accessor properties

参考资料

【书】《JavaScript 高级程序设计(第三版)》

【文章】Object: Data Property and Accessor Property(推荐)

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

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

相关文章

  • 深入理解JavaScript中的属性特性

    摘要:深入理解中的属性和特性中属性和特性是完全不同的两个概念,这里我将根据自己所学,来深入理解中的属性和特性。其中第三个参数描述符对象是对象字面量的方法创建的,里面的属性和属性值实际上保存的是要修改的特性和特性值。 深入理解JavaScript中的属性和特性   JavaScript中属性和特性是完全不同的两个概念,这里我将根据自己所学,来深入理解JavaScript中的属性和特性。   主...

    VPointer 评论0 收藏0
  • javascript 面向对象版块之对象属性

    摘要:上一篇面向对象版块之理解对象下一篇面向对象版块之定义多个对象属性以及读取属性特性 这是 javascript 面向对象版块的第二篇文章,主要讲解的是对象的属性,首先创建一个对象: var person = { name: Nicholas, age: 29, job: Software Engineer, sayName: function () { conso...

    lolomaco 评论0 收藏0
  • 重温JS基础--JS中的对象属性

    摘要:数据属性有个描述其行为的特性表示能否通过删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。总结一波关于这些内容主要讲的就是在的对象属性可以分为两类,一类就是数据属性,一类就是访问器属性。 前言 面向对象的语言都有一个类的概念,通过类可以创建任意多个具有相同属性和方法的对象。 JavaScript中把对象定义为无序属性的集合,属性可以包含基本值,对象或者函数...

    jerryloveemily 评论0 收藏0
  • Javascript面向对象的程序设计_理解对象

    摘要:面向对象的程序设计理解对象前言最近在细读高级程序设计,对于我而言,中文版,书中很多地方翻译的差强人意,所以用自己所理解的,尝试解读下。总结如果英语水平足够好的话,建议看英文原版书籍或者国外大师的博客。 JS面向对象的程序设计_理解对象 前言:最近在细读Javascript高级程序设计,对于我而言,中文版,书中很多地方翻译的差强人意,所以用自己所理解的,尝试解读下。 如有纰漏或错误,会非...

    刘厚水 评论0 收藏0
  • 关于JavaScript对象,你所不知道的事(二)- 再说属性

    摘要:但好在还给我们提供了一个方法,每一个对象都有这样一个方法,专门用来判断某个属性是否是该对象的私有属性。如果你想要用对象字面形式,你只能在创建对象时定义访问器属性。在中,我们使用冻结一个对象,并且使用来判断一个对象是否被冻结。 说完了对象那些不常用的冷知识,是时候来看看JavaScript中对象属性有哪些有意思的东西了。 不出你所料,对象属性自然也有其相应的特征属性,但是这个话题有点复杂...

    Richard_Gao 评论0 收藏0

发表评论

0条评论

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