构造函数(constructor function)
在大部分的面向对象编程语言中,构造函数是类的一个成员方法,用于类的实例化时初始化对象的。不过在JavaScript里并没有“类”(class)的概念(ES5之后加入了’class’关键词),虽然没有‘类’来创建对象,但是对象仍然可以通过多种方式创建,其中就有构造函数方式,使用new操作符调用构造函数从而生成一个对象实例。
因此我们也可以这么去理解JavaScript中的构造函数,构造函数只是一些使用new操作符调用的函数。他们并不属于某一个类,也不会实例化一个类!
JavaScript构造函数的书写规则和调用方式
- 书写规则: 构造函数都应该以 一个大写字母开头, 而非构造函数则应该以一个小写字母开头
- 调用方式: 任何函数,只要通过new操作符来调用,那它就可以作为构造函数, 如果不通过new操作符来调用,那它跟普通函数没有什么区别。
我们来看个Case
1 | // use stric |
上面的代码,当构造函数作为普通函数使用时,我们可以发现一些坑, 构造函数与一个普通函数并无不同,如果你故意不使用new,或忘记用new,都会得到怪异的错误:
- person2并不是Person的实例, 其值为undefined
- this指向window, this下的变量和属性变为全局变量和属性。
- 在严格模式下,当你不通过new 调用Person构造函数会出现错误。
构造函数的返回值
JavaScript中构造函数可以有返回值也可以没有。
1.没有返回值的情况像其他传统语言一样,返回实例化的对象
1 | function Person(){ |
2.如果存在返回值则检查其返回值是否为引用类型,如果为非引用类型,如(string,number,boolean,null,undefined),上述几种类型的情况与没有返回值的情况相同,实际返回实例化的对象
1 | function Person(){ |
3.如果存在返回值是引用类型,则实际返回该引用类型
1 | function Person(){ |
new操作符到底都干了啥?
对于上面的Person构造函数,当我们执行var person1 = new Person()是,到底发生了什么?MDN上是这么说的 对于var o = new Foo();1
2
3
4//JavaScript 实际上执行的是:
var o = new Object();
o.[[Prototype]] = Foo.prototype;
Foo.call(o);
我们按照MDN上面的过程来理解下var person1 = new Person()的执行过程
- var obj = new Objec(); // 创建一个空对象obj
- obj.__proto__ = Person.prototype; // obj空对象的原型指向原型对象
- Person.call(obj); // Person构造函数中的this指向对象obj
- var person1 = obj; // 把这个obj赋给person1, 完成var person1 = new Person()的过程.
内置构造函数
JavaScript有九种内置的构造函数:Object(), Function(), Array(), Number(), String(), Boolean(), RegExp(), Date(), Error().当我们需要创建这些值的时候,我们可以自由选择使用字面量或者构造函数。但是相同情况下,字面量对象不仅易读,而且运行速度更快,因为他们可以在解析的时候被优化。所以当你需要使用简单对象的时候就使用字面量吧。