JavaScript对象小结

2017-08-14  本文已影响28人  szu_bee

有关原型链与继承的相关知识,参考: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 };
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);
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';
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运算符的左侧是属性名(字符串),右侧是对象。

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*的属性
o.hasOwnProperty("x") // true
o.hasOwnProperty("y") // false
o.hasOwnProperty("toString") // false
var o = Object.create({y: 2});
o.x = 1;
o.propertyIsEnumerable("x") // true
o.propertyIsEnumerable("y") // false 【y是继承来的】
Object.prototype.propertyIsEnumerable("toString") // false 【不可枚举】

枚举属性

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({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()

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}

对象的三个属性

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

var o = [1, 2];
Object.prototype.toString.call(o).slice(8, -1); // 'Array'

序列化对象

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

对象方法

上一篇下一篇

猜你喜欢

热点阅读