简介:到底是什么让我们认为 Foo 是一个“类”呢? 其中一个原因是我们看到了关键字 new,在面向类的语言中构造类实例时也会用到它。另 一个原因是,看起来我们执行了类的构造函数方法,Foo() 的调用方式很像初始化类时类 ...

js“构造函数”

到底是什么让我们认为 Foo 是一个“类”呢? 其中一个原因是我们看到了关键字 new,在面向类的语言中构造类实例时也会用到它。另 一个原因是,看起来我们执行了类的构造函数方法,Foo() 的调用方式很像初始化类时类 构造函数的调用方式。 除了令人迷惑的“构造函数”语义外,Foo.prototype 还有另一个绝招。思考下面的代码:

js“构造函数”

Foo.prototype 默认(在代码中第一行声明时!)有一个公有并且不可枚举的属性 .constructor,这个属性引用的是对象关联的函数(本例中是 Foo)。此外,我们可以看到通过“构造函数”调用 new Foo() 创建的对象也有一个 .constructor 属性,指向 “创建这个对象的函数”。实际上 a 本身并没有 .constructor 属性。而且,虽然 a.constructor 确实指 向 Foo 函数,但是这个属性并不是表示 a 由 Foo“构造”,稍后我们会解释。好吧……按照 JavaScript 世界的惯例,“类”名首字母要大写,所以名字写作 Foo 而 非 foo 似乎也提示它是一个“类”。显而易见,是吧 ?!这个惯例影响力非常大,以至于如果你用 new 来调用小写方法或者不用 new 调用首字母大写的函数,许多 JavaScript 开发者都会责怪你。这很令人吃惊, 我们竟然会如此努力地维护 JavaScript 中(假)“面向类”的权力,尽管对于 JavaScript 引擎来说首字母大写没有任何意义。

构造函数还是调用

上一段代码很容易让人认为 Foo 是一个构造函数,因为我们使用 new 来调用它并且看到它 “构造”了一个对象。 实际上,Foo 和你程序中的其他函数没有任何区别。函数本身并不是构造函数,然而,当 你在普通的函数调用前面加上 new 关键字之后,就会把这个函数调用变成一个“构造函数 调用”。实际上,new 会劫持所有普通函数并用构造对象的形式来调用它。举例来说:

js“构造函数”

NothingSpecial 只是一个普通的函数,但是使用 new 调用时,它就会构造一个对象并赋值 给 a,这看起来像是 new 的一个副作用(无论如何都会构造一个对象)。这个调用是一个构 造函数调用,但是 NothingSpecial 本身并不是一个构造函数。 换句话说,在 JavaScript 中对于“构造函数”最准确的解释是,所有带 new 的函数调用。 函数不是构造函数,但是当且仅当使用 new 时,函数调用会变成“构造函数调用”。

本文仅代表作者个人观点,不代表巅云官方发声,对观点有疑义请先联系作者本人进行修改,若内容非法请联系平台管理员,邮箱2522407257@qq.com。更多相关资讯,请到巅云www.rzxsoft.cn学习互联网营销技术请到巅云建站www.rzxsoft.cn。