面向对象编程 -- 创建对象1
// 虽然使用 Object 构造函数或对象字面量可以方便地创建对象,但这些方式也有明显不足:创建具有同样接口的多个对象需要编写很多代码。
一、概述
// 纵观 ECMAScript 规范的历次发布,每个版本的特性似乎都出人意料。
// ECMAScript 6 开始正式支持类和继承。
二、工厂模式
// 工厂模式是一种众所周知的设计模式,广泛应用于软件工程领域,用于抽象创建特定对象的过程。
function createPerson(name, age, job) {
let o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function() {
console.log(this.name);
};
return o;
}
let person1 = createPerson("Nicholas", 29, "Software Engineer");
let person2 = createPerson("Greg", 27, "Doctor");
三、构造函数模式
// ECMAScript 中的构造函数是用于创建特定类型对象的。
// 前面的例子使用构造函数模式可以这样写:
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function() {
console.log(this.name);
};
}
let person1 = new Person("Nicholas", 29, "Software Engineer");
let person2 = new Person("Greg", 27, "Doctor");
person1.sayName(); // Nicholas
person2.sayName(); // Greg
// person1 和 person2 分别保存着 Person 的不同实例。
console.log(person1.constructor == Person); // true
console.log(person2.constructor == Person); // true
// 前面例子中的每个对象都是 Object 的实例,同样也是 Person 的实例。
console.log(person1 instanceof Object); // true
console.log(person1 instanceof Person); // true
console.log(person2 instanceof Object); // true
console.log(person2 instanceof Person); // true
1.构造函数也是函数
// 构造函数与普通函数唯一的区别就是调用方式不同。
// 用作构造函数
let person = new Person("Nicholas", 29, "Software Engineer");
person.sayName(); // "Nicholas"
// 作为函数调用
Person("Greg", 27, "Doctor"); // adds to window
window.sayName(); // "Greg"
// 在另一个对象的作用域中调用
let o = new Object();
Person.call(o, "Kristen", 25, "Nurse");
o.sayName(); // "Kristen"
2.构造函数的问题
// 构造函数虽然有用,但也不是没有问题。
// 每次定义函数时,都会初始化一个对象。
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = new Function("console.log(this.name)"); // 逻辑等价
}
// 不同实例上的函数虽然同名却不相等。
console.log(person1.sayName == person2.sayName); // false
// 要解决这个问题,可以把函数定义转移到构造函数外部
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = sayName;
}
function sayName() {
console.log(this.name);
}
let person1 = new Person("Nicholas", 29, "Software Engineer");
let person2 = new Person("Greg", 27, "Doctor");
person1.sayName(); // Nicholas
person2.sayName(); // Greg
console.log(person1.sayName == person2.sayName);