创建对象的一个重要方式是使用构造函数,构造函数以大写字母开头,构造函数必须始终使用特殊关键字 new 来调用,
与普通函数的区别是:普通函数必须创建将返回的对象并直接修改该对象,而构造函数会自动创建对象,
然后,为了向此对象中添加属性或方法,需要使用特殊的关键字 this
。
- 要实例化(即 创建 )一个新的对象,我们可以使用
new
运算符来调用这个函数:new SoftwareDeveloper()
;
构造函数:结构和语法
function SoftwareDeveloper() { |
首先,构造函数并不声明局部变量,而是使用 this
关键字来保存数据。以上函数将为所创建的任何对象添加一个 favoriteLanguage
属性,并为其分配一个默认值 ‘JavaScript’。现在不用太在意构造函数中的 this
;只要知道 this
是指在构造函数前面使用 new
关键字创建的新对象即可。我们很快就会详细介绍这个 this
!
最后一点比较特别的是,这个函数似乎不会返回任何东西!JavaScript
中的构造函数不应该有一个显式的返回值(即使用 return
语句)。
创建一个新的对象
正如我们在上面看到的,让我们使用 new 运算符来创建一个新的对象:
let developer = new SoftwareDeveloper(); |
我们已经把这个调用的返回值保存到了变量 developer
中。让我们执行 console.log(developer)
; 将这个 SoftwareDeveloper
对象记录到控制台:
console.log(developer); // SoftwareDeveloper {favoriteLanguage: "JavaScript"} |
用对象字面量的方式来创建对象,看看有何不同
let orderDeveloper = { favoriteLanguage: 'JavaScript' }; |
可以看出 与 developer
相比,创建对象的构造函数 SoftwareDeveloper
没有列在Chrome 开发者工具中;
在 Chrome 开发者工具中 构造函数通常显示在 {} 前面;developer
的构造函数是 SoftwareDeveloper
,而 orderDeveloper
的构造函数是 object
构造函数;比较之下,两者原型将有所不同。
构造函数可以有参数
与常规函数一样,使用构造函数的一个好处是它们也可以接受参数。让我们更新以上构造函数来接受一个参数,并为其分配 name 属性:
function SoftwareDeveloper(name) { |
在更新的 SoftwareDeveloper()
函数中,无论传入函数的值是什么,它都将是对象的 name
属性的值。让我们来看看:
let instructor = new SoftwareDeveloper('Andrew'); |
正如我们在上面看到的,我们可以使用相同的构造函数来创建不同的对象:
let teacher = new SoftwareDeveloper('Richard'); |
构造函数的好处是,我们可以调用相同的构造函数,创建无数个实例或对象。
省略 new 运算符
如果你无意中 没有 使用 new
运算符来调用构造函数,会发生什么?
function SoftwareDeveloper(name) { |
这是怎么回事?如果不使用 new
运算符,则不会创建对象。该函数会像任何其他常规函数一样被调用。由于该函数不会 _返回_ 任何东西(除了所有函数都会默认返回的 undefined 之外),因此 coder
变量最终会被分配给 undefined
。
还有一点需要注意:由于这个函数作为一个常规函数被调用,因此 this
的值也会截然不同。现在不用太在意这一点,我们将在下一部分深入探讨 this
关键字!
查看对象的构造函数(instanceof)
如果我们想查看某个对象是否是用构造函数创建的呢?我们可以使用 instanceof
(它会返回一个布尔值)来窥见一些端倪。让我们来看看吧!
function Developer(name){ |
instanceof 和原型链
在以上示例中,instanceof
确认一个特定的构造函数确实创建了一个特定的对象。我们知道这一点,是因为我们在调用 Developer()
构造函数之后直接实例化了 dev
对象。
然而,很多时候并没有这么简单:instanceof 运算符实际上会测试构造函数是否出现在某个对象的原型链中。这意味着,虽然我们不是总能检查到底是 哪个构造函数 创建了该对象,但是它使我们能够洞察某个对象可能访问哪些其他的属性和方法。
小结
JavaScript 的类系统是直接使用函数和对象来构建的。使用 new 运算符来调用构造函数可以实例化一个新的对象。相同的构造函数可以用于创建不同的对象。
我们在整篇中广泛讨论了函数、对象和 this。事实证明,这三者是密切相关的! 我们将在下一部分深入探讨 this 关键字,并仔细分析这三者之间的关系。