一、基本用法简介

声明一个简单的对象,如下

var obj = {
name: 'ldld'
}

 我们可以用Object.defineProperty来声明这个对象

var obj = {}
Object.defineProperty(obj,'name',{
value:'ldld',
writable:true,
enumerable: true,
configurable: true
})

下列就这四个基本的配置简单介绍一下

  1. value:初始值
  2. writable:是否可以修改该属性的值
    var obj = {}
    Object.defineProperty(obj,'name',{
    value:'ldld',
    writable:false,
    enumerable: true,
    configurable: true
    }) obj.name // 'ldld'
    obj.name = 'LLLL'; // 这里会修改失败,严格模式下会报错 TypeError
    console.log(obj.name) // 'ldld'
  3. enumerable:是否可枚举,这个是否能遍历到该属性(for)
  4.   configurable : 这个得重点讲一下
    var obj = {}
    // 第一次设置操作configurable配置,设置为false
    Object.defineProperty(obj,'name',{
    value:'ldld',
    writable:true,
    enumerable: true,
    configurable: false
    }) obj.name // 'ldld'
    obj.name = 'LLLL'; // configurable: false 不影响writable属性,这里可以设置成功
    console.log(obj.name) // 'LLLL' // 第二次设置操作configurable配置,在第一步false基础上改回true
    Object.defineProperty(obj,'name',{
    value:'ldld',
    writable:true,
    enumerable: true,
    configurable: true // 现在我们想改回来,但是很遗憾,不能。不管是严格模式还是非严格模式都会报错
    })

     此外,configurable会影响该对象属性是否可以被删除

    Object.defineProperty(obj,'name',{
    value:'ldld',
    writable:true,
    enumerable: true,
    configurable: true
    }) delete obj.name;
    console.log(obj.name) // undefined ,说明删除成功 Object.defineProperty(obj,'name',{
    value:'ldld',
    writable:true,
    enumerable: true,
    configurable: false
    }) delete obj.name;
    console.log(obj.name) // ldld, 说明name属性没有被删除

二、对象常量

const str = 'abc';
str = 'def'; // 报错Uncaught TypeError: Assignment to constant variable. const obj = {name:'ldld'};
obj.name = {
name:'ldld1234' // 这里会修改成功
}

  const声明的对象不可变,实际上是可以理解为指针的不可变。

const str = 'abc';  表示str指针指向栈中一个地址,值'abc';

str = 'def';表示str又指到另一个地址,值为'def',违反了不可变的规则,报错了。

const obj = {name:'ldld'};表示obj 对象指向一个堆 内存堆的obj的引用,不管怎么改变obj里面的值,在内存堆中地方始终不变,因此不会报错。

那么问题来了,我们想声明一个不可变的对象,那怎么办?可以参考如下:

var obj = {}
Object.defineProperty(obj,'name',{
value:'ldld',
writable:false,
configurable: false
})
// 此时问obj的name属性不可改变了。

  但是问题来来,name是不能再改变,但是我们可以给对象扩展其他属性。。。

三、防止对象扩展Object.preventExtensions

var obj = {}
Object.defineProperty(obj,'name',{
value:'ldld',
writable:false,
configurable: false
})
// 此时问obj的name属性不可改变了。但是可以扩展obj属性
obj.age = 100;
console.log(obj.age) // 100 Object.preventExtensions(obj);
obj.sex = 'male';
console.log(obj.sex) // undefined,说明扩展失败

  

四、密封Object.seal

顾名思义,密封一个对象,这个对象不能配置,不能扩展属性,不能删除属性。但是可以可以修改熟悉过的值

Object.seal(obj)// 等同于如下:代码1 + 代码2
// 代码1
Object.defineProperty(obj,'[该对象所有的属性]',{
configurable: false
// writable:true, // 此时默认为true,可以修改
})
// 代码2
Object.preventExtensions(obj);

  

四、冻结Object.freeze(obj)

Object.freeze(obj)// 等同于如下:代码1 + 代码2
// 代码1
Object.seal(obj)
// 代码2
Object.defineProperty(obj,'[该对象所有的属性]',{
writable:false
})

  

由此可见,冻结,就是定一个对象常量的终极大法。


javascript-object对象属性操作之Object.defineProperty的更多相关文章

  1. JavaScript 之 对象属性的特性 和defineProperty方法

    对象是无序属性的集合,而这些属性在创建是都带有一些特征值(可以理解为属性的属性,天生自带的),这些特征值是为了实现JavaScript引擎用的,因此JavaScript不能直接访问. JavaScri ...

  2. js object 对象 属性和方法的使用

    //object 对象 属性和方法的使用 var person = new Object(); person.name="张海"; person.age="; perso ...

  3. JavaScript 访问对象属性和方法及区别

    这篇文章主要介绍了浅析JavaScript访问对象属性和方法及区别的相关资料,仅供参考 属性是一个变量,用来表示一个对象的特征,如颜色.大小.重量等:方法是一个函数,用来表示对象的操作,如奔跑.呼吸. ...

  4. 转: JavaScript 获取对象属性和方法

    一.获取对象属性和方法 Object.keys()for in 返回对象的可枚举属性和方法的名称数组. Object.getOwnPropertyNames() 返回的数组的所有属性(可枚举或不可枚举 ...

  5. JavaScript 获取对象属性和方法

    ShineJaie 原创整理,转载请注明出处. 一.获取对象属性和方法 Object.keys() 返回对象的可枚举属性和方法的名称数组. Object.getOwnPropertyNames() 返 ...

  6. 2018-06-27 jq文档处理与jq对象属性操作

    jQ文档处理: 内部插入 A.append(B) ->把B后追加到A内部中 B.appendTo(A) ->把B后追加到A内部中 A.prepend(B) ->把B后追加到A内部中 ...

  7. js 中object对象的操作

    n = object对象 for(var p in n){ console.log(p);// 取得是key值 console.log(n[p]);//取得是value值 } 继之前js中数组的常用方 ...

  8. js - object的属性操作

    视频学习地址: http://www.imooc.com/video/6002 原文PPT下载地址: http://img.mukewang.com/down/54c5ec1a000141f10000 ...

  9. 获取Object对象属性的方法,Reflect.ownKeys, Object.getOwnPropertyNames,Object.getOwnPropertySymbols,Object.keys,for in

    let triangle={ a:1, b:2, c:3 } function coloTriangle(){ this.color='red'; } coloTriangle.prototype=t ...

随机推荐

  1. sqlMap.xml配置文件中迭代一个集合的方式

    比如:根据班级号查询学生的信息,参数是list 1.foreach的用法:[写法一] <select id="getStudentListByClassId" resultM ...

  2. Flash存储模块调试

    Flash存储模块 Flash存储模块之前SPI一直读deviceID有问题原因如下: 用正点原子的例程是可以的,但是转移到自己的工程项目里就不行!!原因是正点原子没有在SPI初始化里     RCC ...

  3. Vue源码详细解析:transclude,compile,link,依赖,批处理...一网打尽,全解析!

    用了Vue很久了,最近决定系统性的看看Vue的源码,相信看源码的同学不在少数,但是看的时候却发现挺有难度,Vue虽然足够精简,但是怎么说现在也有10k行的代码量了,深入进去逐行查看的时候感觉内容庞杂并 ...

  4. JDK11 | 第四篇 : 增强API

    文章首发于公众号<程序员果果> 地址 : https://mp.weixin.qq.com/s/O0xntC-JfeSBk-9x2QfwnA 一.简介 JDK 9~11 在语言语法方面有一 ...

  5. SCUT - 131 - 小P玩游戏II - 贪心 - 平衡树

    https://scut.online/p/131 首先假如钦定了一群人去打怪兽,那么可以把主要的任务都丢给b最大的人去打,这样不会更差.然后考虑枚举这个b最大的人,其他人陪练.一开始就是ai+k*b ...

  6. java实战应用:MyBatis实现单表的增删改

    MyBatis 是支持普通 SQL查询.存储过程和高级映射的优秀持久层框架.MyBatis 消除了差点儿全部的JDBC代码和參数的手工设置以及结果集的检索.MyBatis 使用简单的 XML或注解用于 ...

  7. Gradle打包问题Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0

    前言 使用gradle打包react native的时候,出现了如下报错,下面和大家说一下解决的具体办法 Deprecated Gradle features were used in this bu ...

  8. postman断言

    较旧的写作邮差测试风格 较旧的Postman测试编写风格依赖于特殊tests对象的设置值.您可以为对象中的元素设置描述性键,然后说明它是真还是假.例如,tests["Body contain ...

  9. C# 获得系统环境

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  10. 一、C++类库与C#类库相互调用

    1.C++调用C#类库 1.准备C#类库(dll文件) 1.1.创建C#类库: 右击项目类库生成即可, 出现.dll(类库)与.pdb(pdb文件包含了编译后程序指向源代码的位置信息, 用于调试的时候 ...