JS面向对象设计-理解对象

不同于其他面向对象语言(OO,Object-Oriented),JS的ECMAScript没有类的概念,

它把对象定义为"无序属性(基本值、对象、函数)的集合",类似于散列表.

每个对象都是基于一个引用类型(原生类型、自定义类型)创建的.

1. 理解对象

创建自定义对象(Object构造函数、对象字面量).

// Object构造函数:创建一个Object实例,再为实例添加属性和方法.
var person = new Object();
person.name = "xiao";
person.getName = function() {
console.log(this.name) // 被解析为person.name
} // 对象字面量: 属性在创建时带有一些特征值,JS通过特征值来定义它们的行为.
var person = {
name: "xiao";
getName: function() {
console.log(this.name)
}
}

1.1 属性类型(数据属性、访问器属性)

[[ ]]: 内部值(内部才用的特性)实现JS引擎,描述属性各种特征,JS不能直接访问.

1.1.1 数据属性

  • [[Configurable]]可用delete删除属性从而重新定义属性,修改属性特性、改为访问器属性.
  • [[Enumberable]]可用for-in循环返回属性.
  • [[Writable]]可修改属性值.
  • [[Value]]属性的数据值,默认为undefined.

ps. 直接在对象上定义的属性,他们的Configurable,Enumberable,Writable特性都为true.

修改属性默认的特性:Object.defineProperty()

/*
* 参数
* 1.属性所在对象
* 2.属性名字
* 3.一个描述符对象,描述符对象的属性必须是(configurable、enumerable、writable、value)
*/
var person = {};
Object.defineProperty(person, "name", {
writable: false, // 属性只读
value: "xiao"
})
console.log(person.name); // "xiao"
person.name = "da"; // 非严格模式下被忽视,严格模式下报错
console.log(person.name); // "xiao"
// 一旦属性定义为不可配置,将不能再把它变回可配置.
Object.defineProperty(person, "name", {
configurable: false, // 属性不可配置
value: "xiao"
})

ps. 用Object.defineproperty()方法创建新属性,如果不指定,Configurable,Enumberable,Writable特性默认为false.

1.1.2 访问器属性

不包含数据值,包含一对getter、setter函数(都不是必需的)

  • [[Configurable]]可用delete删除属性从而重新定义属性,修改属性特性、改为数据属性.
  • [[Enumberable]]可用for-in循环返回属性.
  • [[Get]]读取属性时调用的函数,默认为undefined.
  • [[Set]]写入属性时调用的函数,默认为undefined.

ps. 访问器属性不能直接定义,必须使用Object.defineProperty()

// 常见使用方式:设置一个属性的值会导致其他属性发生变化
var book = {
_year: 2018, // 只能通过对象方法访问的属性
edition: 1
}; Object.defineProperty(book, "year", {
get: function() { // __definGetter__
return this._year;
},
set: function(newValue) { // __definSetter__
if (newValue > 2018) {
this._year = newValue;
this.edition += newValue - 2018;
}
}
}); book.year = 2019; // 修改year属性会导致_year变成2019
console.log(book.edition); // edition变成2

在不支持Object.definProperty()方法的浏览器中不能修改[[Configurable]]和[[Enumberable]]

1.2 定义多个属性

Object.defineProperties()一次定义多个属性

/*
* 参数
* 1.要添加或修改其属性的对象
* 2.第二个对象的属性与第一个对象要添加或修改的属性一一对应
*/
var book = {};
Object.defineProperties(book, {
_year: {
writable: true,
value: 2018
},
edition: {
writable: true,
value: 1
},
year: {
get: function() {
return this._year;
},
set: function(newValue) {
if (newValue > 2018) {
this._year = newValue;
this.edition += newValue - 2018;
}
}
}
})

1.3 读取属性特性

Object.getOwnPropertyDescriptor()取得给定属性的描述符,返回值是一个对象(属性特有的特性)。

/*
* 参数
* 1.属性所在对象
* 2.要读取其描述符的属性名称
*/
var descriptor = Object.getOwnPropertyDescriptor(book, "_year");
console.log(descriptor.value); // 2018
console.log(descriptor.configurable); // false
console.log(descriptor.get); // "undefined",是数据属性,不是访问器属性 var descriptor = Object.getOwnPropertyDescriptor(book, "year");
console.log(descriptor.value); // undefined,是访问器属性,不是数据属性
console.log(descriptor.configurable); // false
console.log(descriptor.get); // "function",是一个指向getter函数的指针

在JS中可以针对任何对象(包括DOM、BOM)使用Object.getOwnPropertyDescriptor()方法.

上一篇:rocketmq控制台搭建(rocketmq-console)


下一篇:JavaScript: 理解对象