写出几种创建对象的方式,并说说他们的区别是什么?
初见此题,没啥好说的,脑海中闪现如下两种方式:
//字面量
var obj={};
//new实例化
var obj=new Object();难度就这么点?百度查了查,发现自己理解得有些片面了。如下正解:
工厂方式创建对象
function createPerson(name) {
var obj = {};
obj.name = name;
obj.sayMyname = function() {
console.log(this.name);
};
return obj;
}
var p1 = createPerson('Mike');
p1.sayMyname(); //Mike
var p2 = createPerson('Lily');
p2.sayMyname(); //Lily
console.log(p1 instanceof createPerson); //false
console.log(p1 instanceof Object); //true
console.log(p2 instanceof createPerson); //false
console.log(p2 instanceof Object); //true可以明显的感觉到,用此方法创建的对象无法识别创造者(这里的创造者全是Object)。
构造函数创建对象
当new去调用一个函数,这个时候函数中的this就是创建出来的对象,而且函数的返回值就是this(隐式返回)。
function createPerson(name) {
this.name = name;
this.sayMyname = function() {
console.log(this.name);
};
}
var p1 = new createPerson('Mike');
p1.sayMyname(); //Mike
var p2 = new createPerson('Lily');
p2.sayMyname(); //Lily
console.log(p1 instanceof createPerson); //true
console.log(p1 instanceof Object); //true
console.log(p2 instanceof createPerson); //true
console.log(p2 instanceof Object); //true- 优点:创建自定义函数意味着将来可以将它的实例标识为一种特定的类型,这是构造函数胜过工厂模式的地方
- 缺点:每个方法都要在每个实例上重新创建一遍,如(sayMyname)
原型方式
function Person() {}
Person.prototype.name = 'Mike';
Person.prototype.sayMyname = function() {
console.log(this.name);
};
var p1 = new Person();
p1.sayMyname();- 优点:可以让所有的对象实例共享它所包含的属性和方法
- 缺点:原型中是所有属性都是共享的,但是实例一般都是要有自己的单独属性的。所以一般很少单独使用原型模式。
混合模型
- 构造函数模式定义实例属性
- 原型模式用于定义方法和共享的属性
function CreatePerson(name) { this.name = name;}CreatePerson.prototype.sayMyname = function() { console.log(this.name);};var p1 = new CreatePerson('Mike');p1.sayMyname();var p2 = new CreatePerson('Lily');p2.sayMyname();console.log(p1.sayMyname == p2.sayMyname); //true;原因:都是在原型下面,在内存中只存在一份,地址相同属性是否要放在原型下面,就要看该属性是否是可变的,如果不是可变的,就可以放在原型下面,用来公用属性,可变的话放在构造函数下面。