Object.definePropety
defineProperty
Object.defineProperty()方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象,也就是说,该方法允许精确地添加或修改对象的属性。
语法
Object.defineProperty(obj, prop, descriptor)
obj: 要定义属性的对象。
prop: 要定义或修改的属性的名称或Symbol。
descriptor: 要定义或修改的属性描述符。
属性描述符
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的。存取描述符是由getter函数和setter函数所描述的属性。一个描述符只能是数据描述符和存取描述符这两者其中之一,不能同时是两者。
| 属性描述符 | configurable | enumerable | value | writable | get | set |
|---|---|---|---|---|---|---|
| 数据描述符 | 可以 | 可以 | 可以 | 可以 | 不可以 | 不可以 |
| 存取描述符 | 可以 | 可以 | 不可以 | 不可以 | 可以 | 可以 |
如果一个描述符不具有value、writable、get和set中的任意一个键,那么它将被认为是一个数据描述符。如果一个描述符同时拥有value或writable和get或set键,则会产生一个异常。 |
||||||
此外,这些选项不一定是自身属性,也要考虑继承来的属性。为了确认保留这些默认值,在设置之前,可能要冻结Object.prototype,明确指定所有的选项,或者通过Object.create(null)将 __proto__属性指向null。 |
configurable
当且仅当该属性的configurable键值为true时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除,默认为false,默认值是指在使用Object.defineProperty()定义属性时的默认值。
"use strict";
// 非严格模式下操作静默失败,即不报错也没有任何效果
// 严格模式下操作失败抛出异常
var obj = {};
Object.defineProperty(obj, "key", {
configurable: true,
value: 1
});
console.log(obj.key); // 1
Object.defineProperty(obj, "key", {
enumerable: true // configurable为true时可以改变描述符
});
delete obj.key; // configurable为true时可以删除属性
console.log(obj.key); // undefined
"use strict";
var obj = {};
Object.defineProperty(obj, "key", {
configurable: false,
value: 1
});
console.log(obj.key); // 1
Object.defineProperty(obj, "key", {
enumerable: true // configurable为false时不可以改变描述符 // Uncaught TypeError: Cannot redefine property: key
});
delete obj.key; // configurable为false时不可以删除属性 // Uncaught TypeError: Cannot delete property 'key' of #<Object>
console.log(obj.key); // undefined
enumerable
当且仅当该属性的enumerable键值为true时,该属性才会出现在对象的枚举属性中,默认为 false。
"use strict";
var obj = { a: 1 };
Object.defineProperty(obj, "key", {
enumerable: true,
value: 1
});
for(let item in obj) console.log(item, obj[item]);
/*
a 1
key 1
*/
"use strict";
var obj = { a: 1 };
Object.defineProperty(obj, "key", {
enumerable: false,
value: 1
});
for(let item in obj) console.log(item, obj[item]);
/*
a 1
*/
value
该属性对应的值,可以是任何有效的JavaScript值,默认为undefined。
"use strict";
var obj = {};
Object.defineProperty(obj, "key", {
value: 1
});
console.log(obj.key); // 1
"use strict";
var obj = {};
Object.defineProperty(obj, "key", {});
console.log(obj.key); // undefined
writable
当且仅当该属性的writable键值为true时,属性的值,才能被赋值运算符改变,默认为 false。
"use strict";
var obj = {};
Object.defineProperty(obj, "key", {
value: 1,
writable: true
});
console.log(obj.key); // 1
obj.key = 11;
console.log(obj.key); // 11
"use strict";
var obj = {};
Object.defineProperty(obj, "key", {
value: 1,
writable: false,
configurable: true
});
console.log(obj.key); // 1
obj.key = 11; // Uncaught TypeError: Cannot assign to read only property 'key' of object '#<Object>'
Object.defineProperty(obj, "key", {
value: 11 // 可以通过redefine来改变值,注意configurable需要为true
});
console.log(obj.key); // 11
get
属性的getter函数,如果没有getter,则为undefined。当访问该属性时,会调用此函数,执行时不传入任何参数,但是会传入this对象,由于继承关系,这里的this并不一定是定义该属性的对象。该函数的返回值会被用作属性的值,默认为undefined。
"use strict";
var obj = { __x: 1 };
Object.defineProperty(obj, "x", {
get: function(){ return this.__x; }
});
console.log(obj.x); // 1
"use strict";
var obj = { __x: 1 };
Object.defineProperty(obj, "x", {
get: function(){ return this.__x; }
});
console.log(obj.x); // 1
obj.x = 11; // 没有set方法 不能直接赋值 // Uncaught TypeError: Cannot set property x of #<Object> which has only a getter
set
属性的setter函数,如果没有setter,则为undefined。当属性值被修改时,会调用此函数,该方法接收一个参数,且传入赋值时的this对象,从而进行赋值操作,默认为undefined。
"use strict";
var obj = { __x: 1 };
Object.defineProperty(obj, "x", {
set: function(x){ this.__x = x; },
get: function(){ return this.__x; }
});
obj.x = 11;
console.log(obj.x); // 11
"use strict";
var obj = { __x: 1 };
Object.defineProperty(obj, "x", {
set: function(x){
console.log("在赋值前可以进行其他操作");
this.__x = x;
}
});
obj.x = 11;
相关
Js严格模式 https://github.com/WindrunnerMax/EveryDay/blob/master/JavaScript/Js%E4%B8%A5%E6%A0%BC%E6%A8%A1%E5%BC%8F.md
Js遍历对象 https://github.com/WindrunnerMax/EveryDay/blob/master/JavaScript/Js%E9%81%8D%E5%8E%86%E5%AF%B9%E8%B1%A1%E6%80%BB%E7%BB%93.md
每日一题
https://github.com/WindrunnerMax/EveryDay
参考
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
Object.definePropety的更多相关文章
- 关于Object.defineProperty的get和set
面试经常提问vue双向数据绑定的原理,其主要是依赖于Object.definePropety(); Object.definePropety下面有get和set方法. get指读取属性时调用的放法,s ...
- Vue不兼容IE8原因以及Object.defineProperty详解
Vue不兼容IE8原因以及Object.defineProperty详解 原因概述: Vue.js使用了IE8不能模拟的ECMAScript5特性. Vue.js支持所有兼容ES5的浏览器. Vue将 ...
- JavaScript OOP 之「创建对象」
工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...
- vue 笔记备份
Vue实现数据双向绑定的原理:Object.defineProperty() vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty() ...
- 对 Vue 的理解(一)
一.什么是 Vue ? 首先,Vue 是一个 MVVM 框架,M -- 模型,就是用来定义驱动的数据,V -- 视图,是经过数据改变后的 html,VM -- 框架视图,就是用来实现双向绑定的中间桥梁 ...
- 前端知识扫盲-VUE知识篇一(VUE核心知识)
最近对整个前端的知识做了一次复盘,总结了一些知识点,分享给大家有助于加深印象. 想要更加理解透彻的同学,还需要大家自己去查阅资料或者翻看源码.后面会陆续的更新一些相关注知识点的文章. 文章只提出问题, ...
- js inheritance all in one
js inheritance all in one prototype & proto constructor Object.definepropety Object.create() js ...
- 【Vue源码学习】响应式原理探秘
最近准备开启Vue的源码学习,并且每一个Vue的重要知识点都会记录下来.我们知道Vue的核心理念是数据驱动视图,所有操作都只需要在数据层做处理,不必关心视图层的操作.这里先来学习Vue的响应式原理,V ...
- CoreCLR源码探索(一) Object是什么
.Net程序员们每天都在和Object在打交道 如果你问一个.Net程序员什么是Object,他可能会信誓旦旦的告诉你"Object还不简单吗,就是所有类型的基类" 这个答案是对的 ...
- JavaScript Object对象
目录 1. 介绍:阐述 Object 对象. 2. 构造函数:介绍 Object 对象的构造函数. 3. 实例属性:介绍 Object 对象的实例属性:prototype.constructor等等. ...
随机推荐
- 2023第十四届极客大挑战 — PWN WP
WP可能有点简陋,因为是直接从docx导入到博客的,实在不想再重新写了!大家凑合着看吧!哈哈哈,问题不大! pwn方向出自:队友 nc_pwntools 只要过了chal1和chal2即可执行任意命令 ...
- web-云部署上线
- [转帖]create table INITRANS参数分析
https://www.modb.pro/db/44701 1. 内容介绍 Oracle数据库create table时使用INITRANS参数设置数据块ITL事务槽的数量,确保该数据块上 并发事务数 ...
- [转帖]云数据库是杀猪盘么,去掉中间商赚差价,aws数据库性能提升 10 倍!价格便宜十倍。
https://tidb.net/blog/021059f1 于是乎dba中的冯大嘴喊出了云数据库就是杀猪盘.让每个公司自建数据库. 那么有没有一种数据库又便宜又好用呢.有 哪就是tidb数据库. 之 ...
- [转帖]龙叔学ES:Elasticsearch XPACK安全认证
https://juejin.cn/post/7081994919237287950 本文已参与「新人创作礼」活动,一起开启掘金创作之路. Elasticsearch往往存有公司大量的数据,如果安全不 ...
- 【转帖】一道面试题:JVM老年代空间担保机制
面试问题 昨天面试的时候,面试官问的问题: 什么是老年代空间担保机制?担保的过程是什么? 老年代空间担保机制是谁给谁担保? 为什么要有老年代空间担保机制?或者说空间担保机制的目的是什么? 如果没有老年 ...
- [转帖]gcc -O0 -O1 -O2 -O3 四级优化选项及每级分别做什么优化
相关博客http://blog.chinaunix.net/uid-24954950-id-2956476.html 相关博客http://blog.csdn.net/misiter/article/ ...
- 感性理解 int 与 long long 的速度差距 & 感性理解不同取模方法的差距
long long 题该怎么做?#define int long long 会多慢? 有时候,当我们被卡常的时候,不妨想一想,自己在开头定义的 #define int long long 有多大影响? ...
- TypeScript中泛型<T>详细讲解
1.泛型 在定义函数或者接口或者类的时候 不能预先确定要使用的数据类型 而是在使用函数.接口.或者类的时候才能够确定数据类型 这个时候我们就需要使用的是泛型 2.功能描述 我们需要实现一个方法,方法中 ...
- tortoisegit 还原远程分支到某个版本
v2还原到v1 1.强制还原(git reset) 如果使用这种方式还原到v1,将丢失还原到v1到v2之间的所有提交及日志. 1.1显示日志 有save1.save2两条提交记录. 1.2 重置版本( ...