属性分类
对象属性类型分类:数据属性 和 访问器属性
数据属性:
- [Configurable]:是否可配置,是否可删除,属性变更
- [Enumerable]: 是否可枚举, for-in循环中
- [Writable]:是否可修改
- [Value]:数据值
var person = {}
Object.defineProperty(person, 'name', {
configurable: true, // 默认false
enumerable: true, // 默认false
writable: true, // 默认false
value: 'xxx'
})访问器属性:
- [Configurable]:是否可配置,是否可删除,属性变更
- [Enumerable]: 是否可枚举, for-in循环中
- [Get]: 读取属性时自动调用
- [Set]:设置属性时自动调用
var person = {}
Object.defineProperty(person, 'name', {
configurable: true, // 默认false
enumerable: true, // 默认false
get: function() { return this._name },
set: function(xx) { this._name = xx }
})创建对象方式
1. 字面量形式或者 Object 构造函数方式
// 1. 字面量形式
const p1 = {}
// 2. 构造函数形式
const p2 = new Object()
// 3. 构造函数的create方法
const p3 = Object.create() // 支持扩展原型2. 工厂模式
function createPerson(name, age) {
const o = {}
o.name = name
o.age = age
o.sayName = function () {
alert(this.name)
}
return o
}
// 创建对象
const p1 = createPerson('n1', 12)
const p2 = createPerson('n2', 12)封装一些共同属性,解决创建相似对象的问题,但没有解决对象识别问题
3. 构造函数方式
function Person(name, age) {
this.name = name
this.age = age
this.sayName = function () {
alert(this.name)
}
}
const p3 = new Person('p3', 12)
const p4 = new Person('p4', 12)使用构造函数创建对象一共经历了四个过程:
- 创建一个新对象
- 将构造函数的作用域绑定到这个新对象(也就是this指向这个新对象)
- 执行函数中的代码(给新对象添加属性)
- 返回这个新对象
PS: 构造函数只允许返回引用类型的值(也就是构造函数总是会返回一个对象), 返回基本类型的值,例如 number / string/ null / undefined 等无效,会返回这个新对象。
如何保证构造函数总是使用 new 调用的,而不是普通函数形式调用?
function Person(name, age) {
if (!(this instanceOf Person)) return new Person(name, age) // 必须需要使用 new
this.name = name
this.age = age
this.sayName = function () {
alert(this.name)
}
}4. Class 方式
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。
基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已
class Person {
constructor(name, age) {
this.age = age;
this.name = name;
}
sayName() { alert(this.name)
}
}
const p5 = new Person('p12', 12)
const p6 = new Person('p13', 13)
// Class 就是构造函数的语法糖
typeof Person // "function"
Person === Person.prototype.constructor // true