程序员必知:对象的属性类型

简介: 程序员必知:对象的属性类型

对象属性有两种

数据属性

访问器属性

数据属性:有四个特性

【【configurable】】(代表属性是否可配置):当这个属性描述符值为true时,该属性可能会被改变,也可能会被从相应的对象删除,默认为false。

【【enumerable】】(代表属性是否可枚举):表示能否通过for - in循环返回属性,默认为false。

【【value】】(代表属性值):包含这个属性的数据值,读取属性值的时候,从这个位置读;写入属性时,把新的值保存在这个位置,默认为undefined.

【【writable】】(代表属性是否可写):表示能否修改属性的值。

修改属性的特性必须使用Object.defineProperty()。包含三个参数:属性所在的对象,属性的名字,和一个描述符对象。

1 var obj = {

2 x:123,

3 y:456

4 }

5 Object.defineProperty(obj,"x",{

6 value:56,

7 writable:true, //表示可以重新赋值写入

8 enumerable:false, //表示不能被枚举

9 configurable:false //表示不能被配置

10 });

11 console.log(obj.x); //56

12 obj.x = 10;

13 console.log(obj.x); //不能被重新赋值,输出56

14 for(var i in obj){

15 console.log(i); //输出 y

16 }

configurable:false后:

delete obj.x 或对象其他属性无法删除

这个属性后面无法再使用Object.defineProperty()方法重新配置configurable:true。

有一个特殊情况:writable:true可以改为false。但是writable:false无法改为true。

1 var obj = {

2 x:123

3 }

4 //等价于

5 Object.defineProperty(obj,"x",{

6 value:123,

7 writable:true,

8 enumerable:true,

9 configurable:true

10 });

1 var obj = {

2 x:123

3 }

4 Object.defineProperty(obj,"y",{value:123});

用Object.defineProperty()添加一个新的值时,其他三个属性不写,默认为false,如果只是调用此方法修改已定义的属性特性则无此限制。上面代码等价于:

1 var obj = {

2 x:123

3 }

4 Object.defineProperty(obj,"y",{

5 value:123,

6 writable:false,

7 enumerable:false,

8 configurable:false

9 });

可以使用Object.defineProperties()同时设置多个属性

1 var obj = {};

2 Object.defineProperties(obj,{

3 x:{

4 value: "yewenxiang",

5 writable:true

6 },

7 y:{

8 value: "xiangwang",

9 writable:false

10 }

11 });

访问器属性:有四个特性

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

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

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

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

使用访问器属性的常见方式:设置一个属性的值导致其他属性发生变化

1 var obj = {

2 x:2016,

3 y:12

4 };

5 Object.defineProperty(obj,"z",{

6 get:function(){

7 return this.x;

8 }//代码效果参考:http://www.ezhiqi.com/zx/art_418.html,

9 set:function(newValue){

10 if(newValue > 12){

11 this.x = 2017;

12 this.y = 1;

13 }

14 }

15 })

16 console.log(obj.x); //2016

17 console.log(obj.y); //12

18 obj.z = 13;

19 console.log(obj.x); //2017

20 console.log(obj.y); //1

21 console.log(obj.z); //2017

不一定非要同时指定get和set。只设置get代表属性z是不可写的,只能获取,尝试写入会被忽略,严格模式下或报错。同样只设置set代表属性z是不可读的,只能设置,尝试读取会返回undefined,在严格模式会报错。

访问器属性另外一种写法:

1 var obj = {

2 x:1,

3 y:2,

4 z:3,

5 get zhouchang(){

6 return this.x+this.y+this.z;

7 },

8 set change(value){

9 this.x=value;

10 this.y=value;

11 this.z*=value;

12 }

13 };

14 console.log(obj.zhouchang); //6

15 obj.change = 2;

16 console.log(obj.zhouchang); //12

最后可以使用Object.getOwnPropertyDescriptor()方法来获取属性特性的值:有两个参数,属性所在的对象和要被读取其描述符的属性名

访问器属性eg:

    Object.getOwnPropertyDescriptor(obj,"x").configurable或.enumerable或.get或.set

数据属性eg:

    Object.getOwnPropertyDescriptor(obj,"z").configurable或.enumerable或.writable或.value

总结来自javascript高级程序设计一书。

相关文章
|
17天前
|
数据可视化 Java
让星星月亮告诉你,通过反射创建类的实例对象,并通过Unsafe theUnsafe来修改实例对象的私有的String类型的成员属性的值
本文介绍了如何使用 Unsafe 类通过反射机制修改对象的私有属性值。主要包括: 1. 获取 Unsafe 的 theUnsafe 属性:通过反射获取 Unsafe类的私有静态属性theUnsafe,并放开其访问权限,以便后续操作 2. 利用反射创建 User 类的实例对象:通过反射创建User类的实例对象,并定义预期值 3. 利用反射获取实例对象的name属性并修改:通过反射获取 User类实例对象的私有属性name,使用 Unsafe`的compareAndSwapObject方法直接在内存地址上修改属性值 核心代码展示了详细的步骤和逻辑,确保了对私有属性的修改不受 JVM 访问权限的限制
47 4
|
2月前
|
JavaScript 前端开发
avaScript基础知识-对象的属性名和属性值
关于JavaScript对象的属性名和属性值的基础知识介绍。
18 2
avaScript基础知识-对象的属性名和属性值
|
6月前
|
测试技术
反射获取或修改对象属性的值
* 获取单个对象的所有键值对
50 3
|
6月前
|
存储 C# 索引
C#学习相关系列之数据类型类的定义(一)
C#学习相关系列之数据类型类的定义(一)
104 0
|
6月前
|
JavaScript 前端开发 编译器
TypeScript【可选属性、只读属性、额外的属性检查、函数类型、类类型、继承接口】(四)-全面详解(学习总结---从入门到深化)
TypeScript【可选属性、只读属性、额外的属性检查、函数类型、类类型、继承接口】(四)-全面详解(学习总结---从入门到深化)
68 0
|
Java 程序员 PHP
C++的对象与类的含义
C++是一门面向对象的编程语言,理解C++需要掌握类(class)和对象(object)这两个概念。 C++ 中的类(Class)可以看做C语言中结构体(Struct)的升级版。结构体是一种构造类型,可以包含若干成员变量,每个成员变量的类型可以不同;可以通过结构体来定义结构体变量,每个变量拥有相同的性质。例如: #include <stdio.h> //定义结构体 Student struct Student{ //结构体包含的成员变量 char *name; int age; float score; }; //显示结构体的成员变量 void displ
64 0
|
Java
java面试题:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
答:是值传递。Java编程语言只有值传递参数。 当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本。指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的。
12523 0
|
存储 Kotlin
【Kotlin】属性 与 幕后字段 ( 属性声明 | 属性初始化器 | 属性访问器 | field 属性幕后字段 | lateinit 延迟初始化属性 )
【Kotlin】属性 与 幕后字段 ( 属性声明 | 属性初始化器 | 属性访问器 | field 属性幕后字段 | lateinit 延迟初始化属性 )
221 0
【Kotlin】属性 与 幕后字段 ( 属性声明 | 属性初始化器 | 属性访问器 | field 属性幕后字段 | lateinit 延迟初始化属性 )