ECMA-262第5版在定义只有内部才用的特性(attribute)时,描述了属性(property)的各种特征。ECMA-262定义这些特性是为了实现javascript引擎用的,因此在javascript中不能直接访问它们。为了表示特性时内部值,该规范把它们放在了两对方括号中,例如[[Enumerable]]。

数据属性

数据属性包含一个数据值的位置,在这个位置可以读取和写入值。数据属性有4个描述其行为的特性

类别

Value

包含这个属性的数据值。读取属性值的时候,从这个位置读取,写入值得时候,把新值保存在这个位置。这个特性得默认值为undefined

Configurable

表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。直接在对象上定义的属性,它们的这个特性默认值为true

Enumerable

表示能否通过for-in循环返回属性,直接在对象上定义的属性,它们的这个特性默认值为true

Writable

表示能否修改属性的值,直接在对象上定义的属性,它们的这个特性默认值为true

修改

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

// 使用方式
Object.defineProperty( obj, prop, descriptor)
obj:需要定义属性的对象。
prop:需定义或修改的属性的名字。
descriptor:一个包含设置特性的对象
// 例子
var person = {name: "percy"};
Object.defineProperty(person,"name",{
writable: false
});

读取

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

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

注意️

  • 直接在对象上定义的属性,它们的[[Configurable]]、[[Enumerable]]、[[Writable]]特性都被设置为true,[[Value]]特性被设置为了指定的值.

访问器属性

访问器属性不包含数据值,它们包含一对getter和setter函数(这两个函数都不是必须的)。在读取访问器属性时会调用getter函数,这个函数会负责返回有效的值,在写入访问器属性时,会调用setter函数并传入新值。这个函数负责决定如何处理数据。访问器属性有如下4个特性

类别

Configurable

表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为数据属性。直接在对象上定义的属性,这个特性的默认值为true

Enumerable

表示能否通过for-in循环返回属性。直接在对象上定义的属性,这个特性的默认值为true

Get

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

Set

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

定义

访问器属性不能直接定义,必须使用Object.defineProperty()定义单个或者Object.defineProperties()来定义

定义单个。注意️:用Object.defineProperty()定义的访问器属性,其configurable和enumerable默认为false。

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); //

定义多个

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

读取

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

var descriptor = Object.getOwnPropertyDescriptor(girl,"age");
console.log(descriptor.value); //
console.log(descriptor.configurable); // false
console.log(descriptor.writable); // true
console.log(descriptor.get); // undefined
console.log(descriptor.set); // undefined

注意️

用Object.defineProperty()定义的访问器属性,其configurable和enumerable默认为false。

数据属性和访问器属性互相转化

数据属性 -> 访问器属性

属性的特性只能是访问器描述符和数据描述符中的一种,给已有的数据属性加get或set转换为访问器属性时,其属性的value、writable就会被废弃。

// 设置get和set其中任意一个即可转换为访问器属性
Object.defineProperty(person, "year", {
get: function() {
return this._year;
},
set: function(value) {
this._year= value;
}
})
var descriptor = Object.getOwnPropertyDescriptor(person, 'year');
console.log(descriptor); // {get: ƒ, set: ƒ, enumerable: true, configurable: true}

访问器属性 -> 数据属性

将访问器属性转换为数据属性,只需要给现有访问器属性设置value或writable这两个属性描述符中的任意一个即可,其原有的get和set就会被废弃,从而转换为数据属性。

注意️:可以在访问器属性和数据属性间相互转化的属性其configurable特性值必须为true。configurable为false,则不可以将其转换为数据属性。

Object.defineProperty(person, "job", {
configurable: true,
enumerable: true,
get: function() {
return this._job;
},
set: function(value) {
this._job = value;
}
});
// 设置value和writable其中任意一个即可转换为数据属性
Object.defineProperty(person, "job", {
value: 'worker',
writable: true
});
var descriptor = Object.getOwnPropertyDescriptor(person, 'job');
console.log(descriptor); // {value: "worker", writable: true, enumerable: true, configurable: true}

扩展:如何定义对象

定义对象一共有如下四种方式

  • 使用语法结构创建的对象
  • 使用构造器创建的对象
  • 使用 Object.create 创建的对象
  • 使用 class 关键字创建的对象

下面我们分别来给个例子

使用语法结构创建对象

var o = {a: 1};

使用构造器创建对象

function Graph() {
this.vertices = [];
this.edges = [];
}
var g = new Graph();

使用 Object.create 创建对象

var a = {a: 1};
var b = Object.create(a);

使用 class 关键字创建的对象

class Polygon {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
let polygon = new Polygon();

参考

MDN文档

https://blog.csdn.net/weixin_43936704/article/details/103930693https://www.cnblogs.com/he-ming-min/p/11011402.htmlhttps://www.cnblogs.com/absolute-child/p/7188417.html

https://www.cnblogs.com/shiningly/p/9482283.html?utm_source=debugrun&utm_medium=referral

JS的数据属性和访问器属性的更多相关文章

  1. Js中的数据属性和访问器属性

    Js中的数据属性和访问器属性 在javaScript中,对象的属性分为两种类型:数据属性和访问器属性. 一.数据属性 1.数据属性:它包含的是一个数据值的位置,在这可以对数据值进行读写. 2.数据属性 ...

  2. js中属性类型:数据属性与访问器属性

    js中属性类型分为两种:数据属性和访问器属性 在js中,对象都是由名值对构成的,名:就是我们所说的属性名,值就是属性对应的值(基本值.对象.方法). ECMA-262第5版定义了只有内部才用的特性,描 ...

  3. JavaScript 数据属性和访问器属性

    在JavaScript中对象被定义为"无序属性的集合,其属性可以包含基本值.对象或函数."通俗点讲,我们可以把对象理解为一组一组的名值对,其中值可以是数据或函数. 创建自定义对象通 ...

  4. JavaScript 属性类型(数据属性和访问器属性)

    数据属性 数据属性包含一个数据值的位置.在这个位置可以读取和写入值.数据属性有 4 个描述其行为的特性. [[Configurable]]:表示能否通过 delete 删除属性从而重新定义属性,能否修 ...

  5. ECMAScript 5中的数据属性和访问器属性

    简介 ECMAScript 定义的对象中有两种特殊的属性, 这两种特殊的属性在你定义对象属性时就会赋予, 我们在必要时可以改写这两种特殊的属性让其属性的访问更加的合理化, 这两种特殊的属性称呼及作用如 ...

  6. JavaScript数据属性与访问器属性

    ES5中对象的属性可以分为‘数据属性’和‘访问器属性’两种. 数据属性一般用于存储数据数值,访问器属性对应的是set/get操作,不能直接存储数据值. 数据属性特性:value.writable.en ...

  7. javascript对象属性——数据属性和访问器属性

    ECMA-262第五版在定义时,描述了属性property的各种特征,定义这些特性是为了实现javascript引擎用的,为了表示该特性是内部值,规范把它们放在了两对儿方括号中,例如[[Enumera ...

  8. JavaScript中的数据属性和访问器属性

    在学习JavaScript原型(prototype)和原型链(prototype chain)知识的时候,发现数据属性和访问器属性的重要性,通过不断的查找相关知识,浅显理解如下,若有差错,希望不吝赐教 ...

  9. 浅谈Javascript数据属性与访问器属性

    ES5中对象的属性可以分为‘数据属性’和‘访问器属性’两种. 数据属性一般用于存储数据数值,访问器属性对应的是set/get操作,不能直接存储数据值. 数据属性特性:value.writable.en ...

随机推荐

  1. 面试官:连Spring三级缓存都答不好,自己走还是我送你?

    面试官:简历上写了精通Spring,那你回答一下Spring为什么用“三级缓存”去解决循环依赖? 我:.......应该有三个缓存的map结构 面试官:具体回答一下 我:平时没认真深入过 面试官:公司 ...

  2. 使用 forever 启动 vue 需要注意的问题

    forever 是 nodejs 生态中一个用来永久挂起一个应用(当这个应用崩溃时能自己重启)的应用(库). 但用他启动vue的时候必须注意一个问题: 在哪个路径启动vue,就在哪个路径启动forev ...

  3. CCNA - Part10 数据包的通信过程

    这篇文章主要是对数据包在同网段和不同网段的转发流程梳理,使用 ping 命令进行实际抓包测试. 网关的概念: 对于像 PC 等终端设备来说,通过交换机可以实现同网段的通信.但如果想要给其他网段发生数据 ...

  4. python多进程之multiprocessing

    什么是多进程? 简单的理解:单板上运行的一个程序就是一个进程.进程是操作系统分配资源的最小单位,不同的进程之间资源不共享,进程间通信需要使用特定的方式.python提供了自带的multiprocess ...

  5. C++语法小记---类型转换

    类型转换 C++类型转换主要包含两种: 隐式类型转换 小类型向大类型转换 char -> int short ->int int -> unsigned int int -> ...

  6. 167两数之和II-输入有序数组

    from typing import List# 这道题很容易能够想到,只需要遍历两边列表就可以了# 两层循环class Solution: def twoSum(self, numbers: Lis ...

  7. NoSQL数据库-MongoDB 学习(一)

    基本介绍 MongoDB 是为了快速开发互联网 Web 应用而设计的数据库系统 MongoDB 的设计目标是极简.灵活.作为 Web 应用栈的一部分 MongoDB 的数据模型是面向文档的,所谓文档是 ...

  8. dos格式迭代转为unix

    #!/bin/bash function recurse_convert() { local path=$ if [ "$path" == "" ];then ...

  9. SpringBoot之整合Quartz调度框架-基于Spring Boot2.0.2版本

    1.项目基础 项目是基于Spring Boot2.x版本的 2.添加依赖 <!-- quartz依赖 --> <dependency> <groupId>org.s ...

  10. Servlet学习之Tomcat secretRequired配置报错问题

    Tomcat secretRequired配置问题 在启动Tomcat时,控制台可能会出现IllegalArgumentException异常,即"AJP连接器配置secretRequire ...