MXOXW

Life always finds a way.

JavaScript 权威指南-对象

| Comments

6.4检测属性

  • in运算符
  • hasOwnProperty()检测是否是对象自有属性
  • propertyIsEnumerable()是hasProperty()的增强版,只有检测到是自有属性且这个属性的enumerable为true时才返回true。
  • !==判断属性是否undefined(in可以区分不存在的属性和存在但是值为undefined的属性)
1
2
3
4
5
6
7
var o = { x: undefined } // Property is explicitly set to undefined
o.x !== undefined // false: property exists but is undefined
o.y !== undefined // false: property doesn't even exist
"x" in o // true: the property exists
"y" in o // false: the property doesn't exists
delete o.x; // Delete the property x
"x" in o // false: it doesn't exist anymore

6.7属性特性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Object.getOwnPropertyDescriptor({x:1}, "x");    //获得某个对象特定属性的属性描述符
//Object.getPrototypeOf()

var o = {}; // Start with no properties at all
// Add a nonenumerable data property x with value 1.
Object.defineProperty(o, "x", { value : 1,
writable: true,
enumerable: false,
configurable: true});
// Check that the property is there but is nonenumerable
o.x; // => 1
Object.keys(o) // => []
// Now modify the property x so that it is read-only
Object.defineProperty(o, "x", { writable: false });
// Try to change the value of the property
o.x = 2; // Fails silently or throws TypeError in strict mode
o.x // => 1
// The property is still configurable, so we can change its value like this:
Object.defineProperty(o, "x", { value: 2 });
o.x // => 2
// Now change x from a data property to an accessor property
Object.defineProperty(o, "x", { get: function() { return 0; } });
o.x // => 0

/**
同时修改或者创建多个属性
**/

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
}
});
  • 如果对象是不可扩展的,则可以编辑已有的自有属性,但不能给它添加新属性。
  • 如果属性是不可配置的,则不能修改它的可配置性和可枚举性。
  • 如果存取器属性是不可配置的,则不能修改其gette了和setter方法,也不能将它转换为数据属性。
  • 如果数据属性是不可配置的,则不能将它转换为存取器属性。
  • 如果数据属性是不可配置的,则不能将它的可写性从fa15e修改为true,但可以从true修改为false。
  • 如果数据属性是不可配置且不可写的,则不能修改它的值。然而可配置但不可写属性的值是可以修改的(实际上是先将它标记为可写的,然后修改它的值,最后转换为不可写的)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* 复制属性的特性
* 给object.prototype添加一个不可枚举的extend()方法
* 这个方法继承自调用它的对象,将作为参数传人的对象的属性一一复制
* 这个方法继承自调用它的对象,将作为参数传人的对象的属性一一复制
* 参数对象的所有自有对象(包括不可枚举的属性)也会一一复制。
*/

Object.defineProperty(Object.prototype,
"extend", // Define Object.prototype.extend
{
writable: true,
enumerable: false, // Make it nonenumerable
configurable: true,
value: function(o) { // Its value is this function
// Get all own props, even nonenumerable ones
var names = Object.getOwnPropertyNames(o);
// Loop through them
for (var i = 0; i < names.length; i++) {
// Skip props already in this object
if (names[i] in this) continue;
// Get property description from o
var desc = Object.getOwnPropertyDescriptor(o, names[i]);
// Use it to create property on this
Object.defineProperty(this, names[i], desc);
}
}
});

6.8对象的属性

  • 原型
  • 可扩展性

6.8.1原型

isPrototypeOf()检测一个对象是否是另一个对象的原型。

1
2
3
4
var p = {x:1}; // Define a prototype object.
var o = Object.create(p); // Create an object with that prototype.
p.isPrototypeOf(o) // => true: o inherits from p
Object.prototype.isPrototypeOf(o) // => true: p inherits from Object.prototype

6.8.2类属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function classof(o) {
if (o === null) return "Null";
if (o === undefined) return "Undefined";
return Object.prototype.toString.call(o).slice(8, -1);
}

classof(null) // => "Null"
classof(1) // => "Number"
classof("") // => "String"
classof(false) // => "Boolean"
classof({}) // => "Object"
classof([]) // => "Array"
classof(/./) // => "Regexp"
classof(new Date()) // => "Date"
classof(window) // => "Window" (a client-side host object)
function f() {}; // Define a custom constructor
classof(new f()); // => "Object"

6.8.3可扩展性

Object.isExtensible()判断对象是否可扩展。
Object.preventExtensions()将对象转换为不可扩展(把对象转换成不可扩展后,就不能再转回可扩展了)。
Object.seal()除了能把对象设置为不可扩展,还可以将对象所有自有属性都设置为不可配置
Object.isSealed()检查对象是不是封闭
Object.freeze()对象设置为不可扩展,还可以将对象所有自有属性都设置为不可配置外,还将它自有的所有数据属性都设置为只读(有setter方法的存取器不受影响)
Object.isFrozen()检测对象是否冻结

6.9对象序列化

JSON.stringify()序列化
JSON.parse()反序列化

6.10对象方法

  • toString()返回一个表示调用这个方法的对象值的字符串。(很多类都带有自定义的toString()方法)
  • toLocalString()返回一个表示这个对象的本地化字符串。
  • toJSON() Object.prototype中实际上没有定义这个方法,但对于需要执行序列号的对象来说,JSON.stringify()方法会调用toJSON()。具体参见Date.toJSON()
  • valueOf()方法,当js需要将对象转换成某种原始值(尤其是转换成数字)而不是字符串时使用。

评论