// (1) define someOne property name
someOne.name = 'cover';
//or use (2)
someOne['name'] = 'cover';
// or use (3) defineProperty
Object.defineProperty(someOne, 'name', {
value : 'cover'
})
从上面看,貌似使用Object.defineProperty很麻烦,那为啥存在这样的方法呢?
带着疑问,我们来看下 Object.defineProperty的定义。
what is Object.defineProperty
The Object.defineProperty() method defines a new property directly on an object, or modifies an exisiting property on an object, and returns the object.
从上面得知,我们可以通过Object.defineProperty
这个方法,直接在一个对象上定义一个新的属性,或者是修改已存在的属性。最终这个方法会返回该对象。
语法
Object.defineProperty(object, propertyname, descriptor)
参数
- object 必需。 要在其上添加或修改属性的对象。 这可能是一个本机 JavaScript对象(即用户定义的对象或内置对象)或 DOM 对象。propertyname 必需。 一个包含属性名称的字符串。descriptor 必需。 属性描述符。 它可以针对数据属性或访问器属性。
属性的状态设置
其中descriptor的参数值得我们关注下,该属性可设置的值有:
- 【value】 属性的值,默认为 undefined。【writable】 该属性是否可写,如果设置成 false,则任何对该属性改写的操作都无效(但不会报错),对于像前面例子中直接在对象上定义的属性,这个属性该特性默认值为为 true。
var someOne = { };
Object.defineProperty(someOne, "name", {
value:"coverguo" , //由于设定了writable属性为false 导致这个量不可以修改
writable: false
});
console.log(someOne.name); // 输出 coverguo
someOne.name = "linkzhu";
console.log(someOne.name); // 输出coverguo
- 【configurable]】如果为false,则任何尝试删除目标属性或修改属性以下特性(writable, configurable, enumerable)的行为将被无效化,对于像前面例子中直接在对象上定义的属性,这个属性该特性默认值为为 true。 。
var someOne = { };
Object.defineProperty(someOne, "name", {
value:"coverguo" ,
configurable: false
});
delete someOne.name;
console.log(someOne.name);// 输出 coverguo
someOne.name = "linkzhu";
console.log(someOne.name); // 输出coverguo
- 【enumerable】 是否能在for-in循环中遍历出来或在Object.keys中列举出来。对于像前面例子中直接在对象上定义的属性,这个属性该特性默认值为为 true。
注意 在调用Object.defineProperty()方法时,如果不指定, configurable, enumerable, writable特性的默认值都是false,这跟之前所 说的对于像前面例子中直接在对象上定义的属性,这个特性默认值为为 true。
并不冲突,如下代码所示:
//调用Object.defineProperty()方法时,如果不指定
var someOne = { };
someOne.name = 'coverguo';
console.log(Object.getOwnPropertyDescriptor(someOne, 'name'));
//输出 Object {value: "coverguo", writable: true, enumerable: true, configurable: true}
//直接在对象上定义的属性,这个特性默认值为为 true
var otherOne = {};
Object.defineProperty(otherOne, "name", {
value:"coverguo"
});
console.log(Object.getOwnPropertyDescriptor(otherOne, 'name'));
//输出 Object {value: "coverguo", writable: false, enumerable: false, configurable: false}
- 【get】一旦目标对象访问该属性,就会调用这个方法,并返回结果。默认为 undefined。【set】 一旦目标对象设置该属性,就会调用这个方法。默认为 undefined。
从上面,可以得知,我们可以通过使用Object.defineProperty,来定义和控制一些特殊的属性,如属性是否可读,属性是否可枚举,甚至修改属性的修改器(setter)和获取器(getter)
那什么场景和地方适合使用到特殊的属性呢?
实际运用
在一些框架,如vue、express、qjs等,经常会看到对Object.defineProperty的使用。那这些框架是如何使用呢?
MVVM中数据‘双向绑定’实现
如vue,qjs等大部分mvvm框架(angular用的是脏处理)都是通过Object.defineProperty来实现数据绑定的 为了更详细的说明,我将在下一篇文章跟大家讲解下。下面篇幅先不展开。(别扔砖。。。)
优化对象获取和修改属性方式
这个优化对象获取和修改属性方式,是什么意思呢? 过去我们在设置dom节点transform时是这样的。
//加入有一个目标节点, 我们想设置其位移时是这样的
var targetDom = document.getElementById('target');
var transformText = 'translateX(' + 10 + 'px)';
targetDom.style.webkitTransform = transformText;
targetDom.style.transform = transformText;
通过上面,可以看到如果页面是需要许多动画时,我们这样编写transform属性是十分蛋疼的。(┬_┬)
但如果通过Object.defineProperty, 我们则可以
//这里只是简单设置下translateX的属性,其他如scale等属性可自己去尝试
Object.defineProperty(dom, 'translateX', {
set: function(value) {
var transformText = 'translateX(' + value + 'px)';
dom.style.webkitTransform = transformText;
dom.style.transform = transformText;
}
//这样再后面调用的时候, 十分简单
dom.translateX = 10;
dom.translateX = -10;
//甚至可以拓展设置如scale, originX, translateZ,等各个属性,达到下面的效果
dom.scale = 1.5; //放大1.5倍
dom.originX = 5; //设置中心点X
}
上面只是个简单的版本,并不是最合理的写法,但主要是为了说明具体的意图和方法
有兴趣了解更多可以看下面这个库:https://github.com/AlloyTeam/AlloyTouch/blob/master/transform.js
增加属性获取和修改时的信息
如在Express4.0中,该版本去除了一些旧版本的中间件,为了让用户能够更好地发现,其有下面这段代码,通过修改get属性方法,让用户调用废弃属性时抛错并带上自定义的错误信息。
[
'json',
'urlencoded',
'bodyParser',
'compress',
'cookieSession',
'session',
'logger',
'cookieParser',
'favicon',
'responseTime',
'errorHandler',
'timeout',
'methodOverride',
'vhost',
'csrf',
'directory',
'limit',
'multipart',
'staticCache',
].forEach(function (name) {
Object.defineProperty(exports, name, {
get: function () {
throw new Error('Most middleware (like ' + name + ') is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.');
},
configurable: true
});
});
其他如设置常量等用途。。。
兼容
相关推荐
在JavaScript中,`Object.defineProperty()`方法是一个非常强大的工具,它允许我们精确地控制对象属性的行为。这个方法在处理数据绑定、访问控制等高级场景时尤为有用。下面将详细讲解`Object.defineProperty()`的...
在JavaScript的世界里,`Object.defineProperty` 是一个非常重要的方法,它允许我们对对象的属性进行精细控制。然而,这个功能在早期版本的IE浏览器(尤其是IE8及以下)中并不支持,这给开发者带来了不小的困扰。`...
Vue 源码学习之 Object.defineProperty 对数组监听 在 Vue 源码学习中,Object.defineProperty 对数组监听是一个非常重要的知识点。本文将详细介绍 Object.defineProperty 对数组监听的原理和实现方法。 Object....
本文介绍了vue源码学习之Object.defineProperty对象属性监听,分享给大家,具体如下: 参考版本 vue源码版本:0.11 相关 vue实现双向数据绑定的关键是 Object.defineProperty ,让我们先来看下这个函数。 在MDN上...
Object.defineProperty() 和 Proxy 对象,都可以用来对数据的劫持操作。何为数据劫持呢?就是在我们访问或者修改某个对象的某个属性的时候,通过一段代码进行拦截行为,然后进行额外的操作,然后返回结果。那么vue中...
在前端开发中,`Object.defineProperty()` 是一个非常重要的 JavaScript API,它允许我们对对象的属性进行细粒度的控制。这个方法是理解 JavaScript 操纵对象属性行为的关键,特别是对于数据绑定、响应式系统和优化...
Vue 使用 Object.defineProperty 实现简单的双向绑定 Vue 中的双向绑定是指视图层(View)和模型层(Model)之间的同步更新。使用 Object.defineProperty 可以手写一个简单的双向绑定示例。 什么是双向绑定? ...
=与Object.defineProperty 为JavaScript对象新增或者修改属性,有两种不同方式:直接使用=赋值或者使用Object.defineProperty()定义。如下: // 示例1 var obj = {}; // 直接使用=赋值 obj.a = 1; // 使用Object....
`Object.defineProperty`是JavaScript语言中的一个非常重要的方法,它允许我们对对象的属性进行精确的控制。这个方法在深入理解JavaScript对象属性特性和优化代码逻辑时具有关键作用。本文将详细探讨`Object....
在实际开发中,`Object.defineProperty()` 常用于实现数据绑定、数据劫持等场景,如Vue.js框架中就广泛使用了这个方法来实现响应式数据。通过这个方法,开发者可以更灵活地控制对象的属性,实现更复杂的数据操作和...
`Object.defineProperty()`是JavaScript中用于对象操作的一个强大方法,它可以让你精确地定义对象的属性,包括属性的值、可写性、可枚举性和可配置性等特性。这个方法接收三个参数:`object`、`propName`和`...
现在前端面试Vue中都会问到响应式原理以及如何实现的,如果你还只是简单回答通过Object.defineProperty()来劫持属性可能已经不够了。 本篇文章通过学习文档及视频教程实现手写一个简易的Vue原始码实现数据双向绑定...
使用Object.defineProperty如果可用); 退回旧发动机的标准配置。 现有属性不会被覆盖。 接受属性名称映射到谓词,该谓词为true时将强制覆盖。例子var define = require ( 'define-properties' ) ;var assert = ...
在JavaScript中,`Object.defineProperty` 是一个非常强大的方法,它允许我们精确地定义或修改对象上的属性。这个方法可以用来创建数据属性和访问器属性,提供了对属性的读写操作的控制,包括读取和修改时的行为。在...
### 浏览器兼容性问题解析:针对IE6、IE7与Firefox的样式处理 在Web开发中,浏览器兼容性始终是一项重要的考虑因素。不同浏览器对CSS的支持程度不一,尤其是对于早期版本的Internet Explorer(IE)如IE6、IE7,以及...
具体到avalon.js的实现,它采用了Object.defineProperty方法,并且针对老旧浏览器采用VBScript进行了兼容处理,使得在这些低级浏览器中也能实现数据的双向绑定。avalon.js的方法虽然比上面提到的简单示例代码复杂得...
通过Object.defineProperty可以实现一些特殊的属性行为,比如,一个属性被设置为不可枚举(enumerable:false),那么它就不会出现在for...in循环和Object.keys()方法返回的数组中。如果设置configurable为false,则...