美文网首页
★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