1、工厂模式
// 定义工厂函数
function createPerson(name, age, hobby) {
// 创建一个临时object对象
var obj = new Object();
// 将工厂函数的参数赋值给临时对象
obj.name = name;
obj.age = age;
obj.hobby = hobby;
obj.sayName = function() {
console.log("我的名字叫:"+this.name);
}
// 返回这个包装好的临时对象
return obj;
}
//使用工厂函数创建对象
var p1 = createPerson('Tom', 12, "sing");
var p2 = createPerson('mayra', 18, "draw");
解决问题:用于创建的批量相似对象
2、构造函数模式
// 定义构造函数
function Person(name, age, hobby) {
this.name = name;
this.age = age;
this.hobby = hobby;
this.sayName = function() {
console.log("我的名字叫:"+this.name);
}
}
// 使用构造函数实例化
var p1 = new Person('Tom', 12, "sing");
var p2 = new Person('mayra', 18, "draw");
步骤分析:
- 使用new关键字在内存中创建一个新对象;
- 将构造函数的this指向这个新对象;
- 使用this为这个对象添加属性和方法
- 返回这个对象
解决的问题:构造函数可以将实例化的对象标识为一种特定的类型
存在的问题:相同的方法每次实例化都要重新创建一遍,浪费内存
3、原型模式
// 定义构造函数
function Person() {
}
// 定义原型
Person.prototype = {
constructor: Person, //重写constructor
name: 'Tom',
books: ['数学','英语'], // 引用类型
country: "china", // 共享属性
sayName: function () { // 共享方法
console.log("我的名字叫:" + this.name);
},
};
// 使用构造函数实例化
var p1 = new Person();
var p2 = new Person();
p1.books.push('语文');
console.log(p1.books); // '数学','英语','语文'
console.log(p2.books); // '数学','英语','语文' p1实例影响到p2!!!
问题:属性和方法都定义在了原型上,1、不能传参构造不同属性的对象 2、对于包含引用类型值的属性来说,实例之间会相互影响
这种单独使用原型模式的方法基本没人使用!
4、构造函数模式和原型模式组合使用(默认使用的模式!!!)
// 定义构造函数
function Person(name, age, hobby) {
this.name = name;
this.age = age;
this.hobby = hobby;
this.books = ['数学','英语']; //引用类型
}
// 定义原型(定义共享的属性)
Person.prototype = {
constructor: Person, //重写constructor
country: "china", // 共享属性
sayName: function () { // 共享方法
console.log("我的名字叫:" + this.name);
},
};
// 使用构造函数实例化
var p1 = new Person('Tom', 12, "sing");
var p2 = new Person('mayra', 18, "draw");
p1.books.push('语文');
console.log(p1.books); // '数学','英语','语文'
console.log(p2.books); // '数学','英语' p1实例不会影响到p2!!!
console.log(p1.country); // china
console.log(p2.country); // china
p1.sayName(); // 我的名字叫:Tom
p2.sayName(); // 我的名字叫:mayra
解决了构造函数模式共享方法多次创建问题,也解决了原型模式出现引用类型属性时存在的问题,目前最为常用的方式
5、动态原型模式
特点:将所有信息都封装在构造函数类,动态初始化原型
// 定义构造函数
function Person(name, age, hobby) {
this.name = name;
this.age = age;
this.hobby = hobby;
// 判断当前是否具有sayName方法,没有就初始化原型添加该方法
if(typeof this.sayName != 'function') {
// 这个只会在第一次使用构造函数时执行
Person.prototype.sayName = function () {
console.log("我的名字叫:" + this.name);
}
}
}
// 使用构造函数实例化
var p1 = new Person('Tom',13,'sing');
var p2 = new Person('bob',16,'draw');
p1.sayName();
p2.sayName();
解决问题:这样构造函数更像一个整体
6、寄生构造函数模式
function Person(name, age, hobby) {
// 创建一个临时object对象
var obj = new Object();
// 将参数赋值给临时对象
obj.name = name;
obj.age = age;
obj.hobby = hobby;
obj.sayName = function() {
console.log("我的名字叫:"+this.name);
};
// 返回这个包装好的临时对象
return obj;
}
//使用函数创建对象
var p1 = new Person('Tom', 12, "sing");
var p2 = new Person('mayra', 18, "draw");
其实就是构造函数样子的工厂模式,意义不大,不推荐使用
7、稳妥构造函数模式
function Person(name) {
// 创建一个临时object对象
var obj = new Object();
obj.sayName = function() {
console.log(this.name);
};
// 返回这个包装好的临时对象
return obj;
}
//函数创建对象
var p1 = new Person('Tom');
var p2 = new Person('mayra');
p1.sayName(); //Tom 只能通过这一种方式访问name的值