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');
与工厂模式不同之处
- 没有显式的创建对象
- 直接将属性直接赋值给this对象
- 没有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是可以调用到处调用,就没有封装性可言了 因此人们又发明一种新的模式,原型