ECMAScript 中的构造函数可以创建特定类型的对象,像Object,Array 这样的原生构造函数,也可以创建自定义的构造函数

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function () {
        console.info(this.name);
    }
}
var person1 = new Person('freax',18,'javascript');
var person2 = new Person('huang',19,'javascript');

与工厂模式不同之处

  1. 没有显式的创建对象
  2. 直接将属性直接赋值给this对象
  3. 没有return 语句

person1 和person2 分别保存不同的实例。并且这两个实例都有一个构造属性,该属性都指向person

console.info(person1.constructor == Person); //true
console.info(person1.constructor == Person); //true

instanceof 检测对象来自那个Constructor函数

constructor构造属性最初是用来识别对象的,但是检测对象类型还是instanceof更加可靠

console.info(person1 instanceof Person); //true
console.info(person1 instanceof Object); //true
console.info(person2 instanceof Person); //true
console.info(person2 instanceof Object); //true

创建自定义的构造函数意味着可以将它 的实例标识为一种特定的类型,而正是构造函数模式胜过工厂模式的地方 person1 和person2 之所以同时是Object的实例,是因为所有对象均继承Object 我们还可以将构造函数当作函数一样调用,因为构造函数也是函数,任何函数使用new操作符调用,那么就可以作为构造函数

既然都是函数也意味也可以像其它函数一样的方式调用

当作构造函数调用

var person = new Person('freax',19,'google');
person.sayName(); //freax

作为普通函数调用

Person('myfreax',19,'google+');
window.sayName(); //myfreax,添加到window中,Person函数内部的this指向了window

构造函数的问题

构造函数模式虽然解决对象识别的问题,但是没有解决对象的中每个函数复用的问题,为何说没有解决函数复用的? 因为在ECMAScript中函数都是对象,因此没,每定义一个函数就实例化一个对象,从逻辑角度上讲,构造函数也可以定义成这样的

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = new Function("console.info(this.name)");
}

从这个角度来看构造函数更容易明白,每个Person实例都包含了一个不同的Function的实例 另外以种方式创建的函数,在不同实例上会有不同的作用域链和标识符的解释,这会导致不同实例上的同名函数不相等

  person1.sayName = person2.sayName; //false

然而我们没有必要为完成一件事同时创建两个不同的Function实例来完成,因此也可以写成这样

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = sayName;
}
function sayName (){
    console.info(this.name);
}

但是这么做就会污染全局作用域,而且sayName是可以调用到处调用,就没有封装性可言了 因此人们又发明一种新的模式,原型