美文网首页
★07.属性

★07.属性

作者: iDragonfly | 来源:发表于2017-07-03 20:01 被阅读0次

    简介

    • 属性名可以是包含空字符串在内的任意字符串,但对象中不能存在两个同名的属性。
    • 值可以是任意 JavaScript 值,从 ES 5 开始也可以是gettersetter函数(或者二者都有)。
    • 属性特性有以下三种:
      • 可写 :是否可以设置属性值。
      • 可枚举 :是否可以通过for/in循环返回该属性值。
      • 可配置 :是否可以删除或修改该属性。
    • ES 5 以前的所有属性都是 可写可枚举可配置 的。

    属性的查询和设置

    • 属性的查询示例:
    var ab = a.b;
    var ac = a["c"];
    
    • 属性的设置示例:
    a.b = 6;
    a["c"] = 7;
    
    • 对象可以动态地创建任意数量的属性。
    • 动态创建对象属性时,通常用[]形式而不是.形式,因为.的属性名用的是标识符,而[]用的属性名师字符串。
    • 对象的 自有属性 可以覆盖 继承属性 ,但 继承属性 即使被 自有属性 覆盖,也仍然存在。
    • 对象的 自有属性 覆盖 继承属性 的示例:
    var o = {r : 1};
    var c = inherit(o);
    c.x = 2;
    c.y = 2;
    c.r = 2;
    o.r;                    // 仍然为1,子对象c的覆盖行为不会影响到原型的属性
    
    • 查询一个对象的不存在属性不会报错,会返回undefined
    • 查询一个不存在的对象的任意属性会抛出 类型错误异常
    • 确保查询的对象存在的简单示例:
    var len = a && a.b && a.b.c;        // JavaScript中的&&不会将操作数转换为布尔值,同时返回的不一定是布尔值,可以是其他真值或假值
    
    • 一些设置属性的操作在 ES 3 中会失败,但不会报错,在 ES 5严格模式 中则报错:
      • 给只读属性赋值。
      • 使用 自有属性 覆盖只读的 继承属性
      • 给不可拓展的对象增加属性。

    删除属性

    • delete只是断开属性和宿主对象的联系。
    • delete只能删除 自有属性 ,不能删除 继承属性 ,可以直接在 原型对象 上删除它。
    • delete的返回值取决于以下两点:
      • delete删除成功或没有任何副作用时,返回true
      • delete后不是一个属性访问表达式,返回true
    • delete不能删除不可配置的属性。在 严格模式 下,删除不可配置的属性会报错。
    o = {x : 1};
    delete o.x;             // true
    delete o.y;             // true
    delete o.toString;      // true
    delete 1;               // true
    
    delete Object.prototype;    // false,无法删除,属性是不可配置的
    var x = 1;                  // false,不可配置
    delete this.x;              // false,无法删除
    function f() { }
    delete this.f;              // false,不能删除全局函数
    

    检测属性

    • in:如果对象的 自有属性继承属性 中包含这个属性就返回true
    var o = {x : 1};
    "x" in o;           // true
    "y" in o;           // false
    "toString" in o;    // true
    
    • hasOwnProperty():如果对象的 自有属性 中包含这个属性就返回true
    var o = {x : 1};
    o.hasOwnProperty("x");                  // true
    o.hasOwnProperty("y");                  // false
    o.hasOwnProperty("toString");           // false
    
    • propertyIsEnumerable():如果对象的可枚举 自有属性 中包含这个属性就返回true。通常 JavaScript 创建的属性都是可枚举的。
    var o = inherit({y : 2});
    o.x = 1;
    o.propertyIsEnumerable("x");                        // true
    o.propertyIsEnumerable("y");                        // false
    Object.prototype.propertyIsEnumerable("toString");  // false
    

    枚举属性

    • for/in循环可以用于遍历对象中所有可枚举的属性(包括 自有属性继承属性 )。
    • 对象继承的内置方法不可枚举的,但在代码中给对象添加的属性都是可枚举的。
    • ES 5 两个和枚举相关的函数:
      • Object.keys():返回一个数组,元素为对象中可枚举的 自有属性 的名称。
      • Object.getOwnPropertyNames():返回一个数组,元素为对象中 自有属性 的名称。

    属性的gettersetter

    • 使用常见的键值对的方式定义的属性,称为 数据属性 。另一种通过定义gettersetter一个或两个的方式定义的属性,称为 存取器属性
    • 数据属性 一样, 存取器属性 也可以被继承。
    • 如果一个 存取器属性
      • 定义了gettersetter则是一个 读/写属性
      • 定义了getter则是一个 只读属性
      • 定义了setter则是一个 只写属性
    • 读取 只写属性 总是返回undefined
    var o = {
        odata = 0;
        get data() { return odata; },             // 逗号
        set data(value) { odata = value; }
    }
    
    o.data;             // 0
    o.data = 10;
    

    属性的特性

    属性描述符

    简述

    • 属性描述符 是一个对象,记录了 数据属性存取器属性 的四个特性。
    • Object.getOwnPropertyDescriptor()
      • 可以用于获取某个对象的 自有属性属性描述符
      • 要想获取 继承属性属性描述符 则需要遍历原型链。
    • Object.definePeoperty()
      • 可以用于设置某个对象的 自有属性属性描述符 ,或者新建具有某种 属性描述符自有属性
      • 要想设置 继承属性属性描述符 则需要遍历原型链。
    • Object.definePeoperties()
      • Object.definePeoperty()一样,但是可以同时设置或新建多个 自有属性
      • 要想设置 继承属性属性描述符 则需要遍历原型链。
    • Object.definePeoperty()Object.definePeoperties()会在违反以下原则时抛出类型错误异常:
      • 如果对象不可拓展,那么可以编辑此对象的 自有属性 ,但是不能添加新属性。
      • 如果属性不可配置,则:
        • 不能修改 可配置性可枚举性
        • 数据属性 转换为 存取器属性 或反方向转换。
        • 可以关闭 可写性 ,但不能打开 可写性

    Object.getOwnPropertyDescriptor()示例

    // 返回 {value: 1, writable:true, enumerable:true, configurable:true}
    Object.getOwnPropertyDescriptor({x : 1}, "x");
    
    var random = {
        get octet() { return Math.floor(Math.random() * 256); }
    };
    
    // 返回 { get: /*func*/, set:undefined, enumerable:true, configurable:true}
    Object.getOwnPropertyDescriptor(random, "octet");
    
    Object.getOwnPropertyDescriptor({}, "x"); // undefined
    Object.getOwnPropertyDescriptor({}, "toString"); // undefined
    

    Object.definePeoperty()示例

    var o = {};
    
    // 定义属性o.x
    Object.defineProperty(o, "x", {
        value : 1,
        writable : true,
        enumerable : false,
        configurable : true
    });
    
    // 设置o.x为不可写
    Object.defineProperty(o, "x", {writable : false});
    
    // o.x虽然不可写,但是仍然可配置,所以可以通过这种方式修改值
    Object.defineProperty(o, "x", {value : 2});
    
    // 可以将数据属性修改为存取器属性
    Object.defineProperty(o, "x", {
        get : function () { return 0; }
    });
    

    Object.definePeoperties()示例

    var p = Object.defineProperties({}, {
        x : {value : 1, writable : true, enumerable : true, configurable : true},
        y : {value : 1, writable : true, enumerable : true, configurable : true},
        r : {
            get : function () {
                return Math.sqrt(this.x * this.x + this.y * this.y)
            },
            enumerable : true,
            configurable : true
        }
    });
    

    数据属性

    • 数据属性 包含以下四个特性:
      • value
      • writable可写性
      • enumerable可枚举性
      • configurable可配置性

    存取器属性

    • 存取器属性 包含以下四个特性:
      • get读取
      • set写入
      • enumerable可枚举性
      • configurable可配置性

    相关文章

      网友评论

          本文标题:★07.属性

          本文链接:https://www.haomeiwen.com/subject/fkpzcxtx.html