虽然用Object构造函数或对象字面量可以创建单个对象,但有一个明显的缺点:使用同一个接口创建对象,会产生大量重复的代码。为此红宝书中又有三种基本的创建对象的方式:
(1)工厂模式
function createPerson(name,age,job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
}
return o;
}
var person1 = createPerson("Bob",23,"programmer");
var person2 = createPerson("Jack",21,"secreter");
1>this指向o;
2>虽然解决了创建多个相似对象的问题,但没法识别对象的类型。
(2)构造函数模式
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function () {
alert(this.name);
};
}
var person1 = new Person("Bob",32,"programmer");
var person2 = new Person("Jack",12,"secreter");
1>没有显式创建对象;
2>直接将属性和方法赋值给this对象;
3>没有return 语句;
4>this指向Person;
(3) 原型模式
function Person() {
}
Person.prototype.name = "Bob";
Person.prototype.age = 23;
Person.prototype.job = "Jack";
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
var person2 = new Person();
1>使用原型模式的好处就是让所有对象实例共享它所包含的属性和方法,不必在构造函数中定义对象实例的信息,将这些信息添加到原型对象上;
2>person1和person2访问的是同一组属性和同一个sayName()函数;
(4)Class中类的基本语法:
Class Person{
constructor(name,age,job){
this.name = name;
this.age = age;
this.job = job;
}
sayName(){
alert(this.name);
}
}
1>constructor()方法中的this指向实例对象,es5的构造函数Person对应es6的Person类的constructor方法;
2> typeof Person // "function"
Person === Person.prototype.constructor // true
类的数据类型是函数,类本身指向构造函数。
class Person{
constructor(){
//...
}
toString(){
//...
}
toValue(){
//...
}
}
//等同于
Person.prototype = {
constructor(){
//...
},
toString(){
//...
},
toValue(){
//...
}
}
let person1 = new Person();
person1.constructor === Person.prototype.constructor // true
在类的实例上调用方法,就是调用原型上的方法。
Object.assign()方法可以向类添加多个方法:
Object.assign(Person.prototype,{
toString(){
//...
},
toValue(){
//...
}
})
prototype对象的constructor属性指向Person,这与es5一致。
类的内部定义的所有方法不可枚举,
类的属性名可以采用表达式。