JavaScript对象小结


有关原型链与继承的相关知识,参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

创建对象

  • 对象直接量 【建议使用】
var empty = {};
var point = { x: 0, y: 1} ;
var point2 = { x: point.x, y: point.y };
  • 通过new创建并初始化一个新对象
var o = new Object();
var arr = new Array();
  • 用自定义构造函数来初始化新对象
function range(from, to) {
  this.from = from;
  this.to = to;
}

range.prototype = {
  // ...
}

var r = range(1, 5);
  • Object.create() 【原型继承法】
var o = Object.create(Object.prototype); // 等价于{} 和 new Object()
var o1 = Object.create({x: 1, y: 2});

属性的查询和设置

  • 属性的查询
    有两种方法
var book = { name: 'hhh', author: 'bee' };
var name = book.name;
var author = book['author']; // 注意[]写法,属性名必须加引号,因为其使用字符串值;若为变量,不加。
  • 属性的设置
    同上,有两种方法可以创建属性或给已有属性赋值
book.name = 'hi';
book['main title'] = 'ES5';
  • 属性访问错误
    查询不存在的属性不会报错(返回undefined),但查询一个不存在的对象会报错。null和undefined都没有属性。
book.subtitle; // undefined
book.subtitle.length // TypeError: Cannot read property 'length' of undefined

只有确定book和book.subtitle都是对象,才能直接写book.subtitle.length。

可利用&&运算符的“短路”行为,写出一种简练的方法来避免出错。

var len = book && book.subtitle && book.subtitle.length;

删除属性

delete运算符只能删除自有属性,不能删除继承属性。

已经删除的属性的引用依然存在:

a = {p: {x: 1}};
b = a.p;
delete a.p;

b.x // => 1

因此,在销毁对象时,要遍历属性中的属性,依次删除,避免造成内存泄漏。

delete不能删除那些可配置性为false的属性。某些内置对象的属性是不可配置的,如通过变量声明和函数声明创建的全局对象属性。

delete Object.prototype // false

var x = 1;
delete this.x; // false

function f() {}
delete this.f; // false

删除全局对象的可配置属性时:

this.x = 1;
delete x; // 非严格模式可用
delete this.x; // 严格模式必须加上对全局对象的引用

检测属性

  • in运算符
    检测对象的自有属性继承属性中是否包含这个属性。

in运算符的左侧是属性名(字符串),右侧是对象。

var o = {x: 1}
"x" in o // true
"y" in o // false
"toString" in o // true

此外,可用"!=="判断一个属性是否是undefined:
o.x !== undefined // true
o.y !== undefined // false
o.toString !== undefined // true

但只有in可区分*不存在的属性*和*存在但值为undefined*的属性
  • hasOwnProperty()
    检测给定的名字是否是对象的自有属性。
o.hasOwnProperty("x") // true
o.hasOwnProperty("y") // false
o.hasOwnProperty("toString") // false
  • propertyIsEnumerable()
    检测这个属性是自有属性且是可枚举的。
var o = Object.create({y: 2});
o.x = 1;
o.propertyIsEnumerable("x") // true
o.propertyIsEnumerable("y") // false 【y是继承来的】
Object.prototype.propertyIsEnumerable("toString") // false 【不可枚举】

枚举属性

  • for/in循环
    可用在循环体中遍历对象中所有可枚举的属性(包括自有和继承的)。

  • Object.keys()
    返回一个由对象中可枚举的自有属性的名称组成的数组。

  • Object.getOwnPropertyNames()
    返回对象的所有自有属性的名称。

var o = {x: 1, y: 2, z: 3};
o.propertyIsEnumerable(x); // true
for (var p in o) { console.log(p); } // x y z

Object.keys(o); // ["x", "y", "z"]

Object.getOwnPropertyNames(Array); // ["length", "name", "arguments", "caller", "prototype", "isArray", "from", "of"]
Object.getOwnPropertyNames(Function); // ["length", "name", "arguments", "caller", "prototype"]

属性getter和setter

详见getter setter

属性的特性

属性包含一个名字和4个特性。4个特性分别是它的值、可写性、可枚举性、可配置性。存取器属性(不具有值特性和可写性,可写性由setter方法存在与否决定)的4个特性是读取、写入、可枚举性、可配置性。

ES5定义了一个名为“属性描述符”(property descriptor)的对象,代表那4个特性。

  • Object.getOwnPropertyDescriptor()
    获得某个对象特定属性的属性描述符。
Object.getOwnPropertyDescriptor({x: 1}, "x") 
// {value: 1, writable: true, enumerable: true, configurable: true}

var random = {
  get octet() { return Math.floor(Math.random() * 256); }
}
Object.getOwnPropertyDescriptor(random, "octet") 
// {set: undefined, enumerable: true, configurable: true, get: ƒ}

要想获得继承属性的特性,需要遍历原型链,参照Object.getPrototypeOf()

  • Object.defineProperty()
    设置属性的特性。
var obj = {key: 'temp'};
Object.getOwnPropertyDescriptor(obj, "key");
// {value: "temp", writable: true, enumerable: true, configurable: true}

Object.defineProperty(obj, "key", {
  enumerable: false,
  configurable: false,
  writable: false,
  value: "static"
}); // {key: "static"}
Object.getOwnPropertyDescriptor(obj, "key");
// {value: "static", writable: false, enumerable: false, configurable: false}

对象的三个属性

  • 原型属性
    Object.getPrototypeOf()
    __proto__用以直接查询/设置对象的原型,但不推荐使用。
    Object.prototype.isPrototypeOf()

  • 类属性
    对象的类属性是一个字符串,用以表示对象的类型信息。

只有一种间接的方法可以查询:默认的toString()方法(继承自Object.prototype)。为了调用正确的(而不是被重写的)toString()版本,必须间接调用Function.call()方法。

var o = [1, 2];
Object.prototype.toString.call(o).slice(8, -1); // 'Array'
  • 可扩展性
    详见Object.isExtensible()

序列化对象

将对象的状态转换为字符串,也可将字符串还原为对象。

  • JSON.stringify()
    序列化对象
  • JSON.parse()
    还原

对象方法

  • toString()
  • toLocaleString()
  • toJSON()
  • valueOf()

你可能感兴趣的:(JavaScript对象小结)