构造函数与new命令
重新定义JavaScript中的构造函数。
构造函数
简述构造函数
JavaScript是一门面向对象语言。
典型的面向对象编程语言(比如 C++ 和 Java),都有“类”(class)这个概念。所谓“类”就是对象的模板,对象就是“类”的实例。但是,JavaScript 语言的对象体系,不是基于“类”的,而是基于构造函数(constructor)和原型链(prototype)。
在JavaScript中,构造函数就是生成对象的模板。所谓”构造函数”,就是专门用来生成实例对象的函数。它就是对象的模板,描述实例对象的基本结构。一个构造函数,可以生成多个实例对象,这些实例对象都有相同的结构。
构造函数有两个特点:
- 函数体内部使用了
this
关键字,代表了所要生成的对象实例。 - 生成对象的时候,必须使用new命令。
重新定义JavaScript中的构造函数
在传统的面向类的语言中,“构造函数”是类的特殊方法,使用new
操作符初始化类时会调用类中的构造函数。
而在JavaScript中,构造函数只是一些使用new
操作符时被调用的函数。
函数本身并不是构造函数,可如果在函数调用前面加上new
关键字,就会把这个函数调用变成一个“构造函数调用”。
可以这么说:实际上并不存在所谓的“构造函数”,只有对函数的“构造调用”。
new 命令
正是因为JavaScript中,构造函数只是一些使用new
操作符时被调用的函数,所以包括内置对象函数(Number(…)…等)在内的所有函数都可以用new
调用。
new命令的原理
当使用new
调用函数时,后面的函数会自动依次执行以下操作:
- 创建一个新的空对象,作为要返回的实例。
- [[prototype]]连接。即将空对象的原型,指向构造函数的
prototype
属性。 - 将空对象绑定到函数内部的
this
。 - 执行函数内部代码。如果函数没有返回其他对象,那么函数自动返回这个新对象。
说一下第4步。
如果构造函数内部有return
语句,而且return
后面一个对象,new
命令会返回return
语句指定的对象;否则,就会不管return语句,返回this对象。
1 | // 推荐的写法 |
上面的代码,由于return返回的是数值,而不是对象,所以new
命令就会忽略这个return
语句,返回“构造”后的this
对象。
但,如果return返回一个对象,哪怕与this
无关,new
都会返回这个对象,而不是this
“构造”的形象。
1 | var Vehicle = function (){ |
前面提到构造函数的一个特点是:“使用了this
关键字,代表了所要生成的对象实例”,为什么呢?
因为,如果对普通函数(内部没有this关键字的函数)使用new命令,则会返回一个空对象。
1 | function getMessage() { |
上面的代码中,getMessage
函数内部没有this
,并return
一个字符串。当new
命令调用对象的时候,执行new
命令的4个步骤:创建了一个空对象,并进行[[prototype]]连接,由于没有this,忽略第3步,新对象没有属性,为空对象。return
语句返回的是字符串,所以new命令就忽略了该语句,并返回创建的对象。
推荐写法
new
命令本身就可以执行构造函数,所以后面的构造函数可以带括号,也可以不带括号。下面两行代码是等价的,但是为了表示这里是函数调用,推荐使用括号。
1 | // 推荐的写法 |