JavaScript 对象创建的几种方式
工厂模式,构造函数,原型模式,动态原型等
Javascript 创建对象的方式
最近看了一些面试题, 发现自己写了一年多的 js 白写了 😂,只是创建对象的几种方式都不知道。搜集了一些资料汇总一下。
工厂模式
function Person() {
var o = new Object();
o.name = "xiao wang";
o.say = function() {
alert(this.name);
};
return o;
}
var person1 = Person();
Pros:
- 完成了返回一个对象的要求。
Cons:
- 无法通过构造方法识别对象,以为都是来自 Object,无法得知是来自 Person。
- 每次通过 Person 创建对象的时候,所有的 say 方法都是一样的,代码冗余,也存储了多次。
构造函数模式
function Person() {
this.name = "xiao wang";
this.say = function() {
alert(this.name);
};
}
var person1 = new Person();
Pros:
- 通过构造方法或者 instanceof 可以识别对象实例的类型。
- 可以通过 new 关键词来创建对象,更接近 OO 语言中创建对象实例的方式。
Cons: 多个实例的 say 方法都是实现同样的效果,却被存储多次,代码冗余。
原型模式
function Person() {}
Person.prototype.name = "mr wang";
Person.prototype.say = function() {
alert(this.name);
};
Person.prototype.friends = ["mr li"];
var person1 = new Person();
Pros:
- say 方法可以共享了,所有实例的 say 方法都指向同一个。
- 可以动态的添加原型对象上的方法和属性,并直接反映在对象实例上。
Cons:
- 所有对象实例共享引用类型变量。(指向同一块内存区域)
- 第一次调用 say 方法或者 name 属性的时候会搜索两次。第一次从实例上寻找 say 方法,然后去原型上去找 say 方法,找到后才会在实例上添加这些方法 or 属性。
- 所有的方法都是共享的,没有办法创建实例自己的属性和方法,也没有办法像构造函数那样传参。
组合使用构造函数模式和原型模式
function Person(name) {
this.name = name;
this.friends = ["mr li"];
}
Person.prototype.say = function() {
console.log(this.name);
};
var person1 = new Person("mr wang");
person1.say();
Pros:
- 解决了原型对象对于应用对象的缺点。
- 解决了原型模式没有办法传递参数的缺点。
- 解决了构造函数模式不能共享方法的缺点。
动态原型模式
function Person(name) {
this.name = name;
if (typeof this.say != "function") {
Person.prototype.say = function() {
alert(this.name);
};
}
}
Pros:
- 可以在初次调用构造函数的时候就完成原型对象的修改。
- 修改能体现在所有的实例中。
寄生构造函数模式
function Person(name) {
var o = new Object();
o.name = name;
o.say = function() {
alert(this.name);
};
return o;
}
var person1 = new Person("mr wang");
Pros:
- 与工厂方法几乎一样,只是可以通过传参确定变量值。
Cons:
- 同工厂模式。
稳妥构造函数模式
function Person(name, job) {
var o = new Object();
o.say = function() {
console.log(name);
console.log(job);
};
return o;
}
var person1 = Person("mr wang", "coder");
person1.say(); // "mr wang", "coder"
person1.name; // undefined;
person1.job; // undefined;
Pros:
- 不向外暴露内部变量,只能通过 say 方法去访问。
Cons:
- 无法通过 instanceof 来判断实例类型。
Last modified on 2020-02-11