用构造函数创建特定类型的对象,从而可以自定义自定义对象类型的属性和方法
与工厂模式的区别
- 没有显示地创建对象
- 直接将属性和方法赋给了this对象
- 没有return语句
- 创建实例时,必须使用
new
操作符
以new创建对象会经历一下步骤- 创建一个新对象
- 将构造函数的作用域赋给新对象(因此this就指向了这个新对象)
- 执行构造函数中的代码
- 返回新对象
constructor属性最初是用来标识对象类型的
示例
var Person = function(name, age) {
this.name = name;
this.age = age;
this.sayName = function() {
return this.name;
};
};
var person1 = new Person('duke', 22);
var person2 = new Person('dome3', 24);
var person3 = Person('no new', 0);
console.log('person1=>', person1);
console.log('person2=>', person2);
console.log('person3=>', person3); // undefined 必须使用new创建对象
console.log('is method equal=>', person1.sayName === person2.sayName); // false
console.log('instance constructor1=>', person1.constructor === Person); // true
console.log('instance constructor2=>', person2.constructor === Person); // true
console.log('instanceof1=>', person1 instanceof Person); // true
console.log('instanceof2=>', person2 instanceof Person); // true
console.log('instanceof2=>', person1 instanceof Object); // true
构造函数也是函数,像普通函数一样,直接调用,属性和方法属于全局对象Global(浏览器中为window对象),如示例中的person3
优点
除了工厂模式的特点,主要解决对象类型识别的问题
缺点
对象的方法,在每个实例中都要重新创建一遍,导致不同的作用域链和标识符解析,但是创建函数实例的机制相同,因此不同实例上的同名函数相同
为了在示例中共享方法而在全局作用域中定义方法,这样能解决以上问题,但是同时产生另外一个问题:在全局作用域中定义的函数只能被某个对象调用,这样全局作用域就有点儿名不副实了,而且若需要定义很多函数,那我们自定义的引用类型就没有封装性可言了
由此,[[原型模式]]可以解决该问题