深入浅出Object.defineProperty()

本文部分参考了书籍《你不知道的javascript》上卷

对象的定义与赋值

经常使用的定义与赋值方法obj.prop = value或者obj['prop'] = value

Object.defineProperty()语法说明

Object.defineProperty()的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性

Object.defineProperty(obj, prop, desc)
  1. obj 需要定义属性的当前对象
  2. prop 当前需要定义的属性名
  3. desc 属性描述符

一般通过为对象的属性赋值的情况下,对象的属性可以修改也可以删除,但是通过Object.defineProperty()定义属性,通过描述符的设置可以进行更精准的控制对象属性

属性的特性以及内部属性

javacript 有三种类型的属性

  1. 命名数据属性:拥有一个确定的值的属性。这也是最常见的属性
  2. 命名访问器属性通过gettersetter进行读取和赋值的属性
  3. 内部属性由JavaScript引擎内部使用的属性,不能通过JavaScript代码直接访问到,不过可以通过一些方法间接的读取和设置。比如,每个对象都有一个内部属性[[Prototype]],你不能直接访问这个属性,但可以通过Object.getPrototypeOf()方法间接的读取到它的值。虽然内部属性通常用一个双中括号包围的名称来表示,但实际上这并不是它们的名字,它们是一种抽象操作,是不可见的,根本没有上面两种属性有的那种字符串类型的属性

属性描述符

通过Object.defineProperty()为对象定义属性,有两种形式,且不能混合使用,分别为数据描述符存取描述符,下面分别描述下两者的区别:

数据描述符 --特有的两个属性(value,writable)

let Person = {}
Object.defineProperty(Person, 'name', {
   value: 'jack',
   writable: true // 是否可以改变
})
let Person = {}
Object.defineProperty(Person, 'name', {
   value: 'jack',
})
//writable默认为false,不能改变属性的值
Person.name='rose'
console.log(Person.name)  //输出为jack
let Person = {}
Object.defineProperty(Person, 'name', {
   value: 'jack',
   writable: true // 是否可以改变
})
Person.name='rose'
console.log(Person.name)  //输出为rose

注意,如果描述符中的某些属性被省略,会使用以下默认规则:

存取描述符 --是由一对 getter、setter 函数功能来描述的属性

get:一个给属性提供getter的方法,如果没有getter则为undefined。该方法返回值被用作属性值。默认为undefined

set:一个给属性提供setter的方法,如果没有setter则为undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认值为undefined

注:setter和getter函数中可以做任意复杂操作。

let Person = {}
let temp = null
Object.defineProperty(Person, 'name', {
  get: function () {
    return temp
  },
  set: function (val) {
    temp = val
  }
})

数据描述符和存取描述均具有以下描述符

  1. configrable 描述属性是否配置,以及可否删除
  2. enumerable 描述属性是否会出现在for in 或者 Object.keys()的遍历中

configrable 代码片段分析

configurable:false不能删除属性

configurable:false不能重新定义属性

等价上一张图的代码

与上一张图的代码进行对比

configurable:true能删除属性

configurable:true能够定义属性

configurable:false与上图做对照

从以上代码运行结果分析总结可知:

  1. configurable: false 时,不能删除当前属性,且不能重新配置当前属性的描述符(有一个小小的意外:可以把writable的状态由true改为false,但是无法由false改为true),但是在writable: true的情况下,可以改变value的值
  2. configurable: true时,可以删除当前属性,可以配置当前属性所有描述符。

enumerable 代码片段分析

注意:以下二种区别

不变性

结合writable: false 和 configurable: false 就可以创建一个真正的常量属性(不可修改,不可重新定义或者删除)

禁止扩展

如果你想禁止一个对象添加新属性并且保留已有属性,就可以使用Object.preventExtensions(...)

禁止扩展片段1

禁止扩展片段2

在非严格模式下,创建属性gender会静默失败,在严格模式下,将会抛出异常。

密封

Object.seal()会创建一个密封的对象,这个方法实际上会在一个现有对象上调用object.preventExtensions(...)并把所有现有属性标记为configurable:false

所以, 密封之后不仅不能添加新属性,也不能重新配置或者删除任何现有属性(虽然可以改属性的值)

冻结

Object.freeze()会创建一个冻结对象,这个方法实际上会在一个现有对象上调用Object.seal(),并把所有现有属性标记为writable: false,这样就无法修改它们的值

这个方法是你可以应用在对象上级别最高的不可变性,它会禁止对于对象本身及其任意直接属性的修改(但是这个对象引用的其他对象是不受影响的)
你可以深度冻结一个对象,具体方法为,首先这个对象上调用Object.freeze()然后遍历它引用的所有对象,并在这些对象上调用Object.freeze()。但是一定要小心,因为这么做有可能会无意中冻结其他共享对象。

属性定义和属性赋值

最后一小节,总结一下上述内容

属性定义,通过Object.defineProperty()形式

1)如果Obj没有名为Prop的自身属性的话:如果Obj是可扩展的话,则创建Prop这个自身属性,否则拒绝

2)如果Obj已经有了名为Prop的自身属性:则按照下面的步骤重新配置这个属性

3)如果这个已有的属性是不可配置的,则进行下面的操作会被拒绝

1: 将一个数据属性转换成访问器属性,反之变然
2: 改变`[[Configurable]]`或`[[Enumerable]]`
3: 改变[[Writable]]由false变为true
4: 在`[[Writable]]`为`false`时改变`[[Value]]`
5: 改变[[Get]]或[[Set]]

否则这个已有的属性可以被重新配置

属性赋值,通过obj.prop = ''prop"形式

1)如果在原型链上存在一个名为P的只读属性(只读的数据属性或者没有setter的访问器属性),则拒绝

2)如果在原型链上存在一个名为P的且拥有setter的访问器属性,则调用这个setter

3)如果没有名为P的自身属性,则如果这个对象是可扩展的,就创建一个新属性,否则,如果这个对象是不可扩展的,则拒绝

4)如果已经存在一个可写的名为P的自身属性,则调用Object.defineProperty(),该操作只会更改P属性的值,其他的特性(比如可枚举性)都不会改变

作用以及影响

属性的定义操作和赋值操作各自有自己的作用和影响。

赋值可能会调用原型上的setter,定义会创建一个自身属性

原型链中的同名只读属性可能会阻止赋值操作,但不会阻止定义操作。如果原型链中存在一个同名的只读属性,则无法通过赋值的方式在原对象上添加这个自身属性,必须使用定义操作才可以。这项限制是在ECMAScript 5.1中引入的

赋值运算符不会改变原型链上的属性
不能通过为obj.foo赋值来改变proto.foo的值。这种操作只会在obj上新建一个自身属性

对象字面量中的属性是通过定义操作添加的。

再次啰嗦一次,记住以下两种形式的区别:

上面的代码等同于:

另一方面:

上面的代码等同于:

转自:深入浅出Object.defineProperty() - 简书 

顺其自然~
关注 关注
  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
vue源码学习之Object.defineProperty 对数组监听
08-27
Vue 源码学习之 Object.defineProperty 对数组监听 在 Vue 源码学习中,Object.defineProperty 对数组监听是一个非常重要的知识点。本文将详细介绍 Object.defineProperty 对数组监听的原理和实现方法。 Object....
vue用Object.defineProperty手写一个简单的双向绑定的示例
08-27
Vue 使用 Object.defineProperty 实现简单的双向绑定 Vue 中的双向绑定是指视图层(View)和模型层(Model)之间的同步更新。使用 Object.defineProperty 可以手写一个简单的双向绑定示例。 什么是双向绑定? ...
JS对象——defineProperty方法简介
热门推荐
qq_43465434的博客
03-07 3万+
defineProperty define:定义 property:属性 defineProperty即给对象定义属性 语法:Object.defineProperty(obj,property,descriptor) 参数一:obj 绑定属性的目标对象 参数二:property 绑定的属性名 参数三:descriptor 属性描述,且此参数本身为一个对象 属性值1:value 设置属性值 属性值2:writable 设置属性是否能够修改 属性值3:enumerable 设置属性是否可以枚举,即是否允许遍
学习笔记——Object.defineProperty()方法
qq_44862029的博客
02-22 3561
一.基本用法 Object.defineProperty()方法是给对象添加属性用的 Object.defineProperty(object, propertyname, descriptor); 其中三个参数分别是: object:对象 propertyname:属性名 descriptor:要添加的属性值 let person = { name: '张三', sex: '男' } Object.defineProperty(person, 'age', { value: 18, //这个a
JavaScript之Object.defineProperty详解
最新发布
Jarvan_I的博客
04-12 381
它允许我们精确地控制对象属性的特性,包括可枚举性、可写性、可配置性等。描述符对象是一个普通的 JavaScript 对象,它有一些可选的键值对,用于定义属性的特性。当需要定义一些特殊属性,比如不可写、不可配置、不可枚举等时,可以使用该方法。当需要对属性进行精确的特性定制时,比如定义计算属性、阻止属性被遍历等。允许我们精确地控制属性的各种特性,包括可写性、可枚举性、可配置性等。可以通过设定属性为不可写、不可配置,防止对属性的误操作。:属性的描述符对象,包含属性的特性。:要定义或修改的属性的名称。
深入理解vue2.x中Object.defineproperty()和vue3.x中Proxy
小陈的博客
02-16 1123
vue2.x中数据的双向绑定主要通过Object.defineproperty()方法实现,data中的数据改变通过对属性设置set属性,获取通过get属性,Object.defineProperty的作用就是劫持一个对象的属性,通常我们对属性的getter和setter方法进行劫持,在对象的属性发生变化时进行特定的操作。而vue3.x主要是通过proxy实现, proxy在目标对象的外层搭建一层拦截,外界对目标对象的某些操作,必须通过这层拦截。
Object.defineProperty()详解
Dragonfly_w的博客
11-30 323
无意间看见的一篇文章,很好,很容易理解,并且也容易上头,转载过来,等老了,逗自己一乐 原文链接 开始 菜菜: “老大,那个, Object.defineProperty 是什么鬼?” 假设我们有个对象 user ; 我们要给它增加一个属性 name , 我们会这么做 1 var user = {}; 2 user.name="狂奔的蜗牛"; 3 console.log(user);//{name: "狂奔的蜗牛"} 如果想要增加一个sayHi方法叻? 1 user.sayHi=function () {
Object.defineProperty()方法详解,原创作品,转载请放链接
m0_58996253的博客
09-13 717
Object.defineProperty
vue源码学习之Object.defineProperty对象属性监听
01-21
本文介绍了vue源码学习之Object.defineProperty对象属性监听,分享给大家,具体如下: 参考版本 vue源码版本:0.11 相关 vue实现双向数据绑定的关键是 Object.defineProperty ,让我们先来看下这个函数。 在MDN上...
详谈Object.defineProperty 及实现数据双向绑定
10-15
`Object.defineProperty()` 是 JavaScript 中用于直接操作对象属性的内置函数,它可以让你精细地控制对象的属性,包括赋值、读取、枚举等行为。在 Vue.js 框架中,`Object.defineProperty()` 被广泛用于实现数据响应...
JavaScript的Object.defineProperty详解
12-10
=与Object.defineProperty 为JavaScript对象新增或者修改属性,有两种不同方式:直接使用=赋值或者使用Object.defineProperty()定义。如下: // 示例1 var obj = {}; // 直接使用=赋值 obj.a = 1; // 使用Object....
js代码-Object.defineProperty()
07-14
js代码-Object.defineProperty()
详解Object.defineProperty()
u014481405的博客
07-10 299
详解Object.defineProperty函数语法1. 参数2. 返回值描述1. 数据描述符和存储描述符共享的可选键值a. configurableb. enumerable2.数据描述符可选键值a. valueb. writable3.数据描述符可选键值a. getb. set4. 描述符默认值汇总5. 描述符可拥有的键值示例1. 创建属性2. 修改属性a. Writable 属性b. Enumerable 属性c. Configurable 属性3. 添加多个属性和默认值4. 自定义 Setters
Vue2和vue3中双向数据绑定的原理,ES6的Proxy对象代理和JavaScript的Object.defineProperty,使用详细
weixin_65793170的博客
07-10 1810
Object.defineProperty大家都知道,是一个强大且常用的方法,用于定义对象属性,允许我们精确地控制属性的行为,包括读取、写入和删除等操作; Proxy是ES6中一种用于创建代理对象的特殊对象,它允许我们拦截并自定义目标对象的操作,例如属性访问、赋值、函数调用等。Proxy提供了一种机制,可以在目标对象上设置拦截器,从而拦截对目标对象的操作。
Object.defineProperty()的用法
小葵坤_易安的博客
08-11 2244
ECMASsript中有两种属性:数据属性和访问器属性 一、属性讲解 数据属性 数据属性包含一个数据值的位置,在这个位置可以读取和写入值,其中有4个描述其行为的特性: Configurable:表示能否通过delete删除此属性,能否修改属性的特性,或能否把属性修改为访问器属性;如果直接使用字面量定义对象,默认值为true Enumerable:表示该属性是否可枚举,即是否通过for-...
defineProperty 详解
weixin_44624120的博客
04-13 820
defineproperty 简单的用defineProperty实现了双向绑定 //defineproperty 有个定义object属性的功能,应该没几个人用,因为相对于obj.a = 1这种方式简直不能再难用。 //通常我们定义obj属性 let obj = { a:1 } obj.b = 2 obj['c'] = 3 console.log(obj)//{a: 1, b: 2,c: 3} Object.defineProperty(obj,'d',{ value:
defineProperty属性的理解与使用
qq_41998083的博客
01-04 5918
defineProperty的参数 defineProperty(obj,prop,desc) 第一个参数为需要定义属性的对象 第二个参数为需要定义的属性名 第三个参数为属性描述符 var obj={} //为obj对象添加name属性,值为lisa Object.defineProperty(obj,"name",{ value:"lisa" }) console.log(obj) //{name:'lisa'} //为obj对象同时添加多个属性 Object.define
什么是 Object.defineProperty
weixin_39307273的博客
03-03 1150
Object.defineProperty是一个作用强大的方法。凡能够实现双向绑定的MVVM框架都是基于此方法!defineProperty的翻译即是“定义属性”,它不仅仅可定义属性,还可通过它来对属性进行拦截、监听 Object.defineProperty简单应用 var obj = {}; Object.defineProperty(obj, 'hello', { get...
javaScript——标准库——属性描述对象
songshuguowang的专栏
02-19 317
概述 JavaScript 提供了一个内部数据结构,用来描述对象的属性,控制它的行为,比如该属性是否可写、可遍历等等。这个内部数据结构称为“属性描述对象”(attributes object)。每个属性都有自己对应的属性描述对象,保存该属性的一些元信息。 下面是属性描述对象的一个例子。 { value: 123, writable: false, enumerable: tru...
Object.defineProperty called on non-object at Function.defineProperty
08-09
The error message "Object.defineProperty called on non-object" occurs when try to use `Object.defineProperty()` on something that is not an object. To resolve this issue, make sure that you are ...

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • 什么是汇编语言 127413
  • 4款最好用的虚拟机软件简介及对比 121806
  • Java Bean详解 102304
  • 接入层、汇聚层、核心层交换机三者之间的功能详解 93842
  • netstat查看端口状态 91154

最新评论

  • selenium库的基本使用

    CSDN-Ada助手: postman支持并发执行么?

  • IDispatch接口 - GetIDsOfNames和Invoke

    何以解忧_唯有RMB: GetIDsOfNames根据函数名和参数名得到对应的dispid,对于参数dispid有什么意义呢?我试过如果我想获取多个函数名的dispid,发现只能返回第一个函数名的dispid,其它函数名返回的dispid全是-1,查看GetIDsOfName的API说明,理应一次性查询多个函数接口的dispid,有研究过吗?

  • 服务器硬件基础知识

    Rbrth's: 点个赞👍再走

  • 云终端、瘦终端和胖终端三者之间有什么区别

    陶陶然的奋斗哥: MD1000 瘦终端

  • 搭建OpenStack云平台

    xdnabl: 谢谢,已经完成了。应该是我之前有问题。请问大佬有UI界面的使用教程吗?

大家在看

  • Python酷库之旅-第三方库openpyxl(05)
  • 企业AI智能名片微信小程序在实时传播中的应用与价值探讨
  • c++重载输出流(<<)和输入流(>>) 343
  • C语言·动态内存管理 533
  • 46、基于自组织映射神经网络的鸢尾花聚类(matlab) 321

最新文章

  • 手机上部署Phi3、Llama3最新大模型
  • chromedriver下载与安装方法
  • XPath Helper Plus: 提升您的网页数据抓取效率
2024
06月 28篇
05月 15篇
04月 32篇
03月 53篇
02月 12篇
01月 74篇
2023年1005篇
2022年501篇
2021年317篇
2020年328篇
2019年101篇
2018年164篇

目录

目录

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

深圳SEO优化公司广州关键词按天扣费吉祥关键词按天扣费塘坑网站优化推广坂田网站优化按天扣费丹竹头网站推广工具东莞网站关键词优化民治营销型网站建设荷坳关键词按天收费坂田网站优化按天收费东莞阿里店铺托管盐田企业网站制作荷坳百搜标王龙岗网站改版南联seo布吉百度网站优化平湖网站搜索优化坪山seo排名大鹏百度关键词包年推广盐田网站开发观澜企业网站设计东莞网站seo优化东莞网站搜索优化民治百度关键词包年推广盐田SEO按效果付费观澜关键词按天收费广州SEO按天扣费观澜seo网站优化坂田企业网站改版坂田设计公司网站大芬网络广告推广歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化