先看看 MSDN上的描述.  

Adds a property to an object, or modifies attributes of an existing property.

Object.defineProperty(object, propertyname, descriptor)

Arguments
object

Required. The object on which to add or modify the property. This can be a native JavaScript object or a DOM object.

(can be 不等于 must be啊. IE8到底搞什么?另外Safari并不允许DOM object.)

propertyname

Required. A string that contains the property name.

descriptor

Required. A JavaScript object that is a descriptor that describes the property. The definition can be for a data property or an accessor property.

Return Value
The object that was passed to the function.

Remarks

You can use the

Object.defineProperty function to do the following:

  • Add a new property to an object. This occurs when the object does not have the specified property name.

  • Modify attributes of an existing property. This occurs when the object already has the specified property name.(参考后面的注释1)

The property definition is provided in a descriptor object, which describes the attributes of a data property or an accessor property. The descriptor object is a parameter of theObject.defineProperty function.

descriptor 参数: (参考 ECMA262 Edition5 8.12.9章节)


Data descriptor attribute

Description

Default if not specified when you add a property

value

The current value of the property.

undefined

writable

true or false. If writable is set to true, the property value can be changed.

false

enumerable

true or false. If enumerable is set to true, the property can be enumerated by a for…in statement.

false

configurable

true or false. If configurable is set to true, property attributes can be changed, and the property can be deleted.

false


BUG:


1. IE8,普通的 new Object 无法使用此接口.

var o = {};
Object.defineProperty(o,'abc',{value:123}); //抛出异常,不是因为别的.仅仅因为 o是一个普通的js object.
o.abc = 300
alert(o.abc);
而如果 o = window 或一些 DOM Element 等宿主对象 就可以使用此接口.但并不是所有宿主对象都可以. 另一个重要的问题是. 对于Attributes参数缺省情况下,IE8也没有实现 o的abc属性的默认只读.即使,显式加上 writable:false.也如此.不知道这个接口被IE8实现成这个鸟样子,到底还有什么用.

2.IE8 Configurable:false


var o =window;
Object.defineProperty(o,'abc',{value:123,configurable:false});
delete o.a //IE8此处抛出异常.
alert(o.abc);

也就是说.configurable 完全没有意义. 其现象就就如同一个固有的bug那样.参考代码:

window.o = 123;
delete window.o; // IE8 抛出异常. 同样是对象不支持此操作.
3. obj 为window宿主对象模拟 Const.

Object.defineProperty(window,'abc',{value:123,writable:false});
abc = 200;
window.abc = 300;
alert([abc,window.abc]) // ie8,Safari5 300,300  | Chrome,Ie9 123,123
这里就涉及一个很郁闷的问题.IE8 SUCKS,我可以理解但是Safari跟着凑什么热闹呢? 好在, 如果我想要的是模拟 Const 的话 Safari4 早就支持了. 所以我们可以假设IE9+ 可以用这个来模拟 Const 哦.
当然,如果window 换成一个普通的 object, Safari则无此问题.所以这应该是Safari 对 宿主对象实现此接口的一个bug.


注1 :  此问题我仍然有点迷惑.至少从ECMA62 Edition5中的相关定义.感觉所有浏览器的实现都没符合标准.或者是我对标准的理解有误.
参考代码 :
var o = {abc:123};

Object.defineProperty(o,'abc',{value:200,Writable:false}); // writable 而不是 Writable. 写成大写.就被认为特性是缺省的。然后 IsDataDescriptor 就会false.
o.abc = 300;
alert(o.abc)//支持defineProperty的浏览器都打印300. 即writable:false,失效了

对于 对象o,已经通过[[Put]]内部方法设置的属性来说(o.abc =123或例子中json方式),这个属性就是一个 data property .(区别于accessor property,setter getter属性.)其特性集(Writable,Configurable,Enumerable)都会被设为true. 而 {value:200,Writable:false} 这个descriptor object,因为具备value特性. 结果就是对他们俩 进行 IsDataDescriptor内部运算 的结果就将是, 两个就都是true.  而最终进入步骤 10.b(else, the [[Configurable]] field of current is true, so any change is acceptable. 参考8.12.9章节).也就是新的特性应该被应用上去.那么 测试代码的结果就让我感到迷惑了.

而观察DefineOwnProperty的步骤.发现大概只有在进入 步骤 9.b.i 即. 即把abc这个data property 转换为了一个 accessor property.而特性操作就被无视了.  但是进入步骤9的条件是. abc属性的descriptor 和 {value:200,Writable:false}  至少有一个在做 IsDataDescriptor运算时返回false. 但是这一点,在测试代码中明显不可能. 所以我困惑无比. 
我更希望是我对标准的理解有错误.而不是浏览器的实现都有问题.期望我能更早的找到这个问题的答案.
对于这个疑惑终于有了答案. hax,指出了我的悲剧. 我的 descriptor 的 特性名,首字母写成了大写.所以默认为忽略了. 所以 实际上就是进入了 9.b.i 了.  之前特性名都写成大写。之所以感觉上是生效的,是因为默认的都是false. 悲剧的人生啊... 留此贴纪念一下我的悲剧.

转载于:https://www.cnblogs.com/_franky/archive/2011/04/27/2030766.html

Object.defineProperty 接口浏览器实现的bug.和疑惑相关推荐

  1. vue 数据绑定实现的核心 Object.defineProperty()

    vue深入响应式原理 现在是时候深入一下了!Vue 最独特的特性之一,是其非侵入性的响应式系统.数据模型仅仅是普通的 JavaScript 对象.而当你修改它们时,视图会进行更新.这使得状态管理非常简 ...

  2. es6相关面试题:1.rest参数;2.new.target;3.object.defineProperty与Proxy的区别;4.Reflect对象作用;5.lterator迭代器;6.async

    文章目录 说说对ES6中rest参数的理解 说说你对new.target的理解 谈谈object.defineProperty与Proxy的区别 ES6中的Reflect对象有什么用? 简单介绍下ES ...

  3. 详解JavaScript之神奇的Object.defineProperty

    摘要: JavaScript有个很神奇的Object.defineProperty(),了解一下? =与Object.defineProperty 为JavaScript对象新增或者修改属性,有两种不 ...

  4. html 前端传入后台为object_浅谈Object.defineProperty()

    或许看过vue 2.x源码的都会说出那么一两句:Vue的双向绑定是通过Object.defineProperty()进行数据拦截.那么这个方法到底是个什么东西呢? 定义 Object.definePr ...

  5. Proxy 与 Object.defineProperty 优劣对比

    Proxy的优势如下: Proxy可以直接监听对象而非属性: Proxy可以直接监听数组的变化: Proxy有多达13种拦截方法,不限于apply.ownKeys.deleteProperty.has ...

  6. Proxy与Object.defineProperty的优劣对比

    Object.defineProperty 劫持数据 只是对对象的属性进行劫持 无法监听新增属性和删除属性 需要使用 vue.set, vue.delete 深层对象的劫持需要一次性递归 劫持数组时需 ...

  7. Vue2双向绑定,Object.defineProperty、Observe、Compile、Watcher、Dep各显神通,相辅相成

    这个问题真的可以说是一个好问题,毕竟基本上面试时也总会被问到,一问双向绑定原理怎么回事儿啊?就说,用了Object.defineProperty()做得数据劫持,劫持了get()和set(),然后巴拉 ...

  8. Object.defineProperty()

    let obj = {}; let song = '发如雪'; obj.singer = '周杰伦'; Object.defineProperty(obj, 'music', { // 1. valu ...

  9. Vue、angular等框架实现双向绑定的原理,核心机制是使用了Object.defineProperty

    <div id="name"></div> var obj = {};Object.defineProperty(obj, "name" ...

最新文章

  1. Win2003下Exchange2003部署图解之六
  2. c语言for循环语句java,C语言三种类型的循环语句
  3. Android MVP 设计模式
  4. windows渗透大全
  5. html5 查看图片,html5实现图片预览和查看原图
  6. 跳一跳python_微信跳一跳python怎么刷分?跳一跳python怎么使用?
  7. C++ Primer Plus 读书笔记(第4、5章)
  8. 对象池 IObjectPool -- ESBasic 可复用的.NET类库(15)
  9. 信息熵、互信息、KL散度
  10. php 获取access token,百度应用获取Access Token
  11. 激励机制中的经济学和博弈论模型(2)
  12. Xftp6-连接Linux传输文件---干货!!!(无私奉献无需积分)
  13. 数据库入门_查询语句
  14. python分支结构与循环结构
  15. 瑞尔森大学计算机网络专业怎么样,瑞尔森大学怎么样?
  16. 共同好友(java)
  17. 可编辑PDF使用pdfplumber无法抽取出文本和表格
  18. 图形渲染与UWA论坛,mipi官网
  19. 取模运算总结 - 数论
  20. Android齐步走-2(2016-7-1)

热门文章

  1. bzoj 1109: [POI2007]堆积木Klo(二维偏序)
  2. bzoj 1662: [Usaco2006 Nov]Round Numbers 圆环数(枚举)
  3. matlab 纹理映射
  4. cube云原生机器学习平台-架构(四)
  5. python装饰器快速入门
  6. 华为怎么查看手机温度_如果你的华为手机拿去维修,记得打开这个功能,防止秘密被查看...
  7. 【剑指offer】链表中环的入口
  8. Centos打开、关闭、结束tomcat,及查看tomcat运行日志
  9. STM32CUBEF4 实现USB 虚拟串口
  10. java并发包下的lock接口与syschronized关键字的区别