什么是构造函数?
- 构造函数其实就是一个函数,只是用途和普通函数,不太一样(可以用来创建对象 )
- 构造函数一般用于初始化对象
//自定义构造函数
function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
this.sayName = function () {
console.log(this.name);
}
}
var person1 = new Person('zhangsan', 29, 'male');
var person2 = new Person('lisi', 19, 'female');
person1.sayName(); // zhangsan
person2.sayName(); // lisi
用字面量的方式来创建对象,最大的缺点就是,这个对象是一次性的,如果有许多的数据,这个代码就要写好多次,有点小麻烦。自定义构造函数解决了使用对象字面量和内置构造函数new Object
的问题,不用每次创建对象都要重新给对象添加属性的问题
构造函数的特色
- 构造函数一般首字母大写
- 构造函数一般和new关键字结合使用
- 构造函数不需要写返回值
- 因为构造函数默认的返回值为新创建出来的对象
- 如果手动的去设置返回值
- 设置返回值为基本类型,不会对默认返回值有任何影响
- 设置返回值为引用类型,会替换掉默认的返回值
调用构造函数会执行如下操作
(1) 在内存中创建一个新对象。
(2) 这个新对象内部的[[Prototype]]特性被赋值为构造函数的 prototype 属性。
(3) 构造函数内部的 this 被赋值为这个新对象(即 this 指向新对象)。
(4) 执行构造函数内部的代码(给新对象添加属性)。
(5) 默认返回新创建出来的对象
自定义构造函数的问题
构造函数虽然有用,但也不是没有问题。构造函数的主要问题在于,其定义的方法会在每个实例上都创建一遍。在上面的例子中其实相当于做了如下操作
function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
this.sayName = new Function("console.log(this.name)"); // 逻辑等价
}
因为都是做一样的事,所以没必要定义两个不同的 Function 实例。况且,this 对象可以把函数与对象的绑定推迟到运行时。
要解决这个问题,可以把函数定义转移到构造函数外部:
function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
this.sayName = sayName;
}
function sayName() {
console.log(this.name);
}
可是问题又来了,如果对象有很多的函数要定义,那么就要定义很多个全局函数,没有封装性可言了,好在这些问题可以通过使用原型模式来解决。(欲知后事如何,且听下回分解!)