zoukankan      html  css  js  c++  java
  • Javascript Object.defineProperty() Benjamin

    转载声明:

    本文标题:Javascript Object.defineProperty()

    本文链接:http://www.zuojj.com/archives/994.html,转载请注明转自Benjamin-专注前端开发和用户体验

    Javascript作为一种语言,有个美誉,开发者可以重新定义任何事情。虽然这在过去的一些javascript可以,但是ECMAScript5中已经开始得到改变,例如,我们可以使用Object.defineProperty创建一个不能被修改的对象的属性。本文中我们将讲述Object.defineProperty的基本用法。 如果你想在文章开始之前,深入了解Object.defineProperty方法,请戳

    一、基本用法

    假如我想构建一个math.js库,看下面的实例:

    var mathObj = {
    	constants: {
    		"pi": 3.14
    	},
    	areaOfCircle: function(radius) {
    		return this.constants.pi*radius*radius;
    	}
    } 
    

    在上例中,如果有人改变pi的值,那么我们将不会得到正确的计算结果,虽然有很多方法可以解决此问题,但是最简单的方法是使用pi属性不可写。看下面实例:

    var mathObj = {
    	constants: {},
    	areaOfCircle: function(radius) {
    		return this.constants.pi*radius*radius;
    	}
    } 
    
    Object.defineProperty(mathObj.constants, "pi", {
    	value: 3.14,
    	writable: false
    });
    
    mathObj.constants.pi = "Benjamin";
    
    //Outputs: 3.14
    console.log(mathObj.constants.pi);

    Object.defineProperty(obj, prop, descriptor)方法接收三个参数:需要添加或修改属性的对象,属性名称,属性描述options。从上例可以看出,当给pi赋值为“Benjamin”时,最后输出的值还是3.14。 但是如果给math.js使用“use strict",将会报错,和给undefined赋值一样:

    "use strict";
    var mathObj = {
    	constants: {},
    	areaOfCircle: function(radius) {
    		return this.constants.pi*radius*radius;
    	}
    } 
    
    Object.defineProperty(mathObj.constants, "pi", {
    	value: 3.14,
    	writable: false
    });
    
    mathObj.constants.pi = "Benjamin";
    
    //Outputs: Uncaught TypeError: Cannot assign to read only property 'pi' of #<Object> 
    console.log(mathObj.constants.pi);

    第三个参数的options中,writable默认值为false,所以在上例中可以省略,configurable默认值为false,如果你想使用你的库的用户故意重写pi的值,你可以设置configurable值为true。

    Object.defineProperty(principia.constants, "pi", {
        value: 3.14,
        configurable: true
    });

    但是当你使用Object.defineProperty时,也有一种相当大的Hack,即使设置了writable的值,它也不会保持属性值不变的:

    var container = {};
    
    Object.defineProperty(container, "arr", {
        writable: false,
        value: ["a", "b"]
    });
    
    container.arr = ["new array"];
    
    // Outputs: ["a", "b"]
    console.log(container.arr);
    
    container.arr.push("new value");
    
    // Outputs: ["a", "b", "new value"]
    console.log(container.arr);

    arr数组是不可写的,所以始终指向同一个数组,但是数组的成员是可以变化的,所以将来可能会增加锁定数组或者对象来解决此问题。

    二、兼容性

    因为Object.defineProperty方法是ES5的一部分,所以在IE9及现代浏览器,IE8中只得到了部分实现,尽可以使用在DOM对象上,不幸的是,并没有IE8相关的shim来兼容。但是,如果你不需要处理旧的浏览器,defineProperty可能会有你使用的地方。 以上就是对Object.defineProperty方法的描述,文中不妥之处,还望批评指正。

  • 相关阅读:
    C# CodeFirst(EF框架)代码优先创建数据库
    Entity Framework 配置关系(1对1,1对0)
    Entity Framework 配置关系(1对1,1对0)
    EFDbContext的使用
    EFDbContext的使用
    编程模式·观察者模式、事件通知、消息队列三者区别
    编程模式·观察者模式、事件通知、消息队列三者区别
    设计模式发布订阅方式实现异步并发
    设计模式发布订阅方式实现异步并发
    关于访问asp.net网站时登录后的奇怪问题
  • 原文地址:https://www.cnblogs.com/cuew1987/p/4055464.html
Copyright © 2011-2022 走看看