Javascript中对象的Obeject.defineProperty()方法-------------(ES5/个人理解)
在讲到Obeject.defineProperty()方法之前先得说明一下ECMAScript中有两种属性:数据属性和访问器属性。
两种属性存在的意义:描述对象属性(key)的一些特性,因为这些属性是内部值,一般放到 [[两个中括号]] 中。
Object.defineProperty(obj , 'key' , {描述信息,是个对象,类似配置项} ) 方法接收三个参数,属性所在的对象,属性名 和一个描述符对象。
数据属性的描述符是下面的一个或者多个(configurable、enumerable、writable 和 value)
访问器属性的描述符是以下的一个或多个(configurable、enumerable、get 和 set)
通过 Object.defineProperty() 方法,可以创建数据属性(并设定其内部属性),也可以创建访问器属性(访问器属性包含 getter 和 setter函数)
数据属性的各项解释:
enumerable : 可枚举性,是否能通过for-in或者Object.keys来遍历

writable : 可修改(可写入),是否能修改value属性值

value : 属性的属性值 (读出和写入都是从这里读出和保存的),默认undefined 数据属性是可以直接通过 对象.属性obj.key 的形式访问和赋值的

configurable : 是否可配置,当它为false的时候,1、上面三项的true和false值都不能改变了,2、对象本身也不能通过delete来删除3、数据属性和访问器属性也不能来回转化了

访问器属性的各项解释:
configurable 、enumerable同上
get : 读取属性的时候调用,默认值undefined
set : 设置属性的时候调用,默认值undefined
对比数据属性和访问器属性的属性异同

数据属性作用: 修改属性默认的特性 (会新建出数据属性)
访问器的作用: 访问和设置数据属性的属性值,不会创建出 .
1、对象属性的创建对比----- 这里创建的是数据属性不是访问器属性,访问器属性只有一种创建方式
A、字面量创建对象的形式:var obj = {key : value } ------ var person1 = {age : 3} 直接创建了age属性和属性值
B、Object.defineProperty(obj ,'key' {...} )创建对象 ------ var person2 = {}; Object.defineProperty(person2, "age", { value: 3 });
通过统一的操作 :
① console.log(person1 .name) ② person1.age = 4 ③ console.log(person1 .name) 得出 // 3 , 赋给了新的值
① console.log(person2 .name) ② person2.age = 4 ③ console.log(person2 .name) 得出 // 3 , 3 赋值没有成功
原理:
直接在对象上定义的属性var obj = {key : value }(字面量形式和new Object()形式) ,它们的Configurable、Enumerable 和Writable特性都被设置为 true,而Value特性被设置为指定的值
通过 Object.defineProperty()定义的属性 它们的Configurable、Enumerable 和Writable特性都被设置为 false,而Value特性被设置为指定的值,这时候的属性值是只读的

2、重点:数据属性不仅可以直接访问和设置(对象.属性/obj.key的形式),也可以通过定义的访问器(getter setter)来专门访问和设置。


得出结论:
① 通过发现book下面并没有真正的year属性,证明了数据属性并不能根据访问器属性来定义创建,访问器属性只是操作访问器属性,这个属性可以理解为是在get和set这一动态读取和设置的过程中发挥作用。
② set和get是一对勾子(hook)函数,要理解触发机制(是根据调用book.year或者设置book.year=2005这个时间点触发的,所以这个year可以随便取值):就是访问器属性在调用时,实际上对应触发访问器属性中定义的 get 方法(最后返回的值是其中return出来的结果),当对一个对象的某个属性赋值时,则会自动触发调用相应的set函数。(如果不了解运行机制,需要打断点走一遍即可)
③ book只有_year和edtion两个数据属性(是不是数据属性,要看带不带value属性),year不是数据属性(访问属性不包含数据值,也不会显式的写出来),但是但是book.hasOwnProperty("year"); 确实返回 true。说明了访问器属性也属于对象自己添加的属性。只是读写方式和普通的不一样。
3、再来撸一遍代码,看看运行的原理具体是怎样的??

4、怎么区分数据属性还是访问器属性???看里面的描述符对象。两者是不能混用的。

5、js中的属性的理解:
javascript中一共有三种属性:
普通属性:也就是常规的数据属性,这种属性是用户来添加修改等,把它设置成什么样,就返回出来什么样,不会做些额外的事情。 var obj ={name : "yang"};那么console.log(obj.name) //yang
内部属性:比如数组arr的length属性,函数的prototype属性,DOM节点的innerHTML属性,用户赋完值以后,取值的时候,不一定按预期,有时候还会额外的做一些事情,也难以改变他们的行为。
比如说某一数组,它的长度为10, 当我们设置它为11时,它就会增加一个undefined元素,再设置为9时,就会从后面删掉两个元素。
函数的prototype如果被改变,相当于将其父类改变了,会new不同类型的实例。
DOM的innerHTML,我们赋值时是一个字符串,再取出时,这字符串可能会与原来的不一样, 并且在原元素上生成了不一样的子节点。
访问器属性,允许用户在赋值或取值都经过预先设定的函数,从而实现内部属性的那一种特殊效果。
6、应用(可以代替对象中的getter和setter函数)
== 
其他地方:vue框架MVVM的数据双向绑定,数据的实时观察,不同于angular使用的脏检查。
7、和Object.defineProperty()相关的一些对象方法。
obj.propertyIsEnumerable('key')
obj.hasOwnProperty('key') 可以检测出访问器属性
Obeject.getOwnpropertyDescriptor(obj , 'key') 或者描述符对象 ----- 有就返回对象,否则是undefined。
Object.keys(obj)方法,遍历key值 。 当Object.defineProperty()中enumerable为false的时候,是遍历不出来的。
8、其他
Obeject.prototype的configurable是false,代表不可配置
对象obj的toString方法是原型链上的是不可枚举的 obj.propertyIsEnumerable(toString') // false
最后:不要再IE8 及以前版本 中使用 Object.defineProperty()
Javascript中对象的Obeject.defineProperty()方法-------------(ES5/个人理解)的更多相关文章
- javascript中对象的不同创建方法
javascript中的对象与一般的面向对象的程序设计语言(c++,Java等)不同,甚至很少有人说它是面向对象的程序设计语言,因为它没有类.javaScript只有对象,不是类的实例.javascr ...
- 【你不知道的javaScript 上卷 笔记7】javaScript中对象的[[Prototype]]机制
[[Prototype]]机制 [[Prototype]]是对象内部的隐试属性,指向一个内部的链接,这个链接的作用是:如果在对象上没有找到需要的属性或者方法引用,引擎就 会继续在 [[Prototyp ...
- 深入了解JavaScript中的Symbol的使用方法
这篇文章主要介绍了深入了解JavaScript中的Symbol的使用方法,本文针对ES6版本的JS进行讲解,需要的朋友可以参考下 Symbol 是什么? Symbols 不是图标,也不是指在代码中可以 ...
- JavaScript中对象的属性
在JavaScript中,属性决定了一个对象的状态,本文详细的研究了它们是如何工作的. 属性类型 JavaScript中有三种不同类型的属性:命名数据属性(named data properties) ...
- javascript中对象字面量的理解
javascript中对象字面量与数组字面量 第一部分 我们知道JavaScript中的数据类型有基本数据类型和引用类型,其中Object类型就是非常常用的类型.那么如果创建一个Object类型的实例 ...
- 关于JavaScript中对象的继承实现的学习总结
一.原型链 JavaScript 中原型链是实现继承的主要方法.其主要的思想是利用原型让一个引用类型继承另一个引用类型的属性和方法.实现原型链有一种基本模式,其代码如下. function Super ...
- javascript中对象的深度克隆
记录一个常见的面试题,javascript中对象的深度克隆,转载自:http://www.2cto.com/kf/201409/332955.html 今天就聊一下一个常见的笔试.面试题,js中对象的 ...
- 总结Javascript中数组各种去重的方法
相信大家都知道网上关于Javascript中数组去重的方法很多,这篇文章给大家总结Javascript中数组各种去重的方法,相信本文对大家学习和使用Javascript具有一定的参考借鉴价值,有需要的 ...
- JavaScript中对象转换为原始值的规则
JavaScript中对象转换为原始值遵循哪些原则? P52 对象到布尔值对象到布尔值的转换非常简单:所有的对象(包括数字和函数)都转换为true.对于包装对象亦是如此:new Boolean(fal ...
随机推荐
- 非空二叉树的一个有趣的性质:n0 = n2 + 1
对任何非空二叉树T,若n0 表示叶结点的个数.n2 表示度为2 的非叶结点的个数,那么两者满足关系n0 = n2 + 1. 这个性质很有意思,下面我们来证明它. 证明:首先,假设该二叉树有N 个节点, ...
- navicat----------局域网数据库:如何让navicat链接局域网其他的数据库。
1.方法很简单了,找到被链接的数据库,打开以后有一个自带的mysql数据库,打开以后下面有一个user表,把里面的第一条数据的第一个字段改成% 百分号,然后保存,重启服务器,搞定 2.如果是linux ...
- [原创]java WEB学习笔记102:Spring学习---Spring Bean配置:bean配置方式(工厂方法(静态工厂方法 & 实例工厂方法)、FactoryBean) 全类名
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Cannot use object of type yii\db\Connection as array
$pointLog = $conn->createCommand('select * from table1 where is_deleted = 0 AND id1 = :id1 AND id ...
- 在Repeater中嵌套使用Repeater
在一般的网站中浏览类别的用户控件通常都位于大多数 ASP.NET 页的左边,它使用户能够按类别快速的查找产品.最近遇到一个客户,因为在他网站上展示的产品并不多,所以要求在原有类别浏览的基础上将产品也加 ...
- 数位DP 求K进制下0~N的每个数每位上出现的数的总和
好久没写博客了,因为感觉时间比较紧,另一方面没有心思,做的题目比较浅也是另一方面. 热身赛第二场被血虐了好不好,于是决定看看数位DP吧. 进入正题: 如题是一道经(简)典(单)的数位dp. 第一步,对 ...
- AppleWatch___学习笔记(三)iPhone和Apple Watch上的数据同步
WatchKit App类似于之前iOS 8上新推出的App Extension(应用扩展),比如Today Extension(今天扩展)和Share Extension(分享扩展).只要你对iOS ...
- 让hadoop-0.20.2自带的eclipse插件支持eclipse-3.5以上
hadoop-0.20.2自带的eclipse插件是不支持eclipse-3.5以上的,要想让它支持3.5以上就必须重新编译eclipse插件. 首先先修改 hadoop-0.20.2\src\co ...
- C# 的Brush 及相关颜色的操作 (并不是全转)
C# 的Brush 及相关颜色的操作 2013-12-13 14:08 4977人阅读 评论(0) 收藏 ...
- Linux top和负载的说明
转自:http://bbs.linuxtone.org/thread-1684-1-1.html top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windo ...