JavaScript 对象(下)

getter 和 setter:

  1、ES5 里,属性值可以用一个或两个方法代替,这两个方法就是 getter 和 setter,它们使用 get 和 set 进行定义而不是通过 function

  2、由 getter 和 setter 定义的属性称作 “存取器属性”,它不同于“数据属性”,数据属性只有一个简单的值

  3、当查询存取器属性的值时,JavaScript 调用 getter 方法(无参),并由它返回属性存取表达式的值

  4、当设置一个存取器属性的值时,JavaScript 调用 setter 方法,并将赋值表达式右侧的值当作参数传给 setter

let obj = {
x: 1,
y: 1, // 注意 getter 和 setter 没有使用冒号,但函数体结束和下一个方法或数据属性之间有逗号隔开
// 设置一个可读写属性 result
get result() {
return this.x+"+"+this.y+"i";
},
set result(arr) { // 需要参数
if (arr.length != 2)
throw RangeError();
this.x = arr[0];
this.y = arr[1];
}, // 设置一个只写属性 add
set add(arr) {
if (arr.length != 2)
throw RangeError();
this.x += arr[0];
this.y += arr[1];
return this.x+"+"+this.y+"i";
}
} console.log(obj.result); // 使用 getter,输出 1+1i
obj.add = [1, 2]; // 使用 setter
console.log(obj.result); // 输出 2+3i
obj.result = [3, 4];
console.log(obj.result); // 输出 3+4i

注:读取只写属性总是返回 undefined

属性的特征:

  1、除了包含名字和值之外,属性还包含一些标识它们可写、可枚举和可配置的特性

  2、数据属性的 4 个特性:值、可写性、可枚举性和可配置性

  3、存取器特性:读取、写入、可枚举和可配置

  4、数据属性的描述符对象:value、writable、enumerable 和 configurable;存取器属性则用 get 和 set 属性代替 value 和 writable

  5、writable、enumerable 和 configurable 都是布尔值,而 get 和 set 是函数值

  6、通过 Object.getOwnPropertyDescriptor(obj, p) 可获得某个对象特定属性的属性描述符

  7、通过 Object.defineProperty(obj, p, attr) 设置或新建属性的特性,Object.defineProperties(obj, map) 修改或新建多个属性特性

  8、Object.getOwnPropertyDescriptor() 和 Object.defineProperty() 都不能修改继承来的属性

// 通过 Object.getOwnPropertyDescriptor() 可获得某个对象特定属性的属性描述符
console.log(Object.getOwnPropertyDescriptor({x: 1}, "x"));
console.log(Object.getOwnPropertyDescriptor({}, "toString")); // undefined // defineProperty(obj, p, attr) 设置、新建属性
// defineProperties(obj, map)
let o = {};
// 新建多个属性特性
Object.defineProperties(o, {
x: {value: 1, writable: false, enumerable: true},
y: {value: 2, enumerable: true},
z: {value: 3, configurable: true, enumerable: true}
});
console.log(Object.getOwnPropertyDescriptor(o, "x"));
console.log(o.x);
// 把它修改成可修改的
Object.defineProperty(o, "x", {writable: true});
console.log(Object.getOwnPropertyDescriptor(o, "x"));

对象的三个属性:

  1、原型属性:在实例对象创建之初就设置好的,用来继承属性的,可通过将对象作为参数传入 Object.getPrototypeOf() 来查询它的原型

  2、类属性:是一个字符串,用以表示对象的类型信息,只有一种间接方法可以查询它(toString())

  3、可扩展性:用以表示是否可以给对象添加新属性,通过将对象传入 Object.isExtensible(),来判断该对象是否可扩展;通过将对象传入 Object.preventExtensions() 把其转换为不可扩展(无法转换回可扩展);Object.seal() 除了能将对象设置为不可扩展,还可以将对象的所有自有属性都设置为不可配置;Object.isSealed() 来检测对象是否封闭;Object.freeze() 将对象设置为不可扩展和属性不可配置,同时将自有的所有数据属性设置为只读,存取器属性(setter)不受影响

console.log(Object.getPrototypeOf(o));  // 输出 o 的原型 {}
console.log(Object.prototype.toString.call(o).slice(8, -1)); // 输出 "Object"
console.log(Object.prototype.toString.call([]).slice(8, -1)); // 输出 "Array"
console.log(Object.isExtensible(o)); // 判断对象 o 是否可扩展,输出 true
Object.preventExtensions(o); // 将对象转换为不可扩展
console.log(Object.isExtensible(o)); // 输出 false

序列化对象:

  1、我们可以将对象的状态转换为字符串,也可以将字符串还原为对象,ES5 提供了内置函数 JSON.stringify()JSON.parse() 来序列化和还原对象

  2、JSON 的语法是 JavaScript 语法的一个子集,它并不能表示 JavaScript 里所有的值

  3、JSON.stringify() 只能序列化对象可枚举的自有属性

// 若属性里有不可枚举的,则不把它进行转换
let str = JSON.stringify(o);
// 输出 contend: '{"x": 1, "y": 2, "z": 3}' type: string
console.log("contend:", str, "\t type: ", typeof str); let ser = JSON.parse(str); // 转换成对象
// 输出 contend: {x: 1, y: 2, z: 3} type: object
console.log("contend:", ser, "\t type: ", typeof ser);

对象方法:

  1、toString() 方法:无参,返回一个表示调用这个方法的对象值的字符串

  2、toLocaleString() 方法:返回一个表示这个对象的本地化字符串

  3、toJSON() 方法:如果在待序列化的对象中存在这个方法,则调用它,返回一个序列化结果,而不是原始对象

  4、valueOf() 方法:将对象转换为某种原始值而非字符串

console.log(o.toString().slice(8, -1));
console.log(o.toLocaleString().slice(8, -1));
try {
o.toJSON();
} catch(e) {
// 若 toJSON 并未被定义,则会产生 TypeError
console.log("TypeError");
}
console.log(o.valueOf());
上一篇:(转)Unity3D研究院之Assetbundle的实战(六十三)


下一篇:(转载)Unity3D研究院之使用 C#合成解析XML与JSON(四十一)