我注意到我是否有以下内容:
var functionName = function(){console.log("this is a function!")}
调用functionName
等同于functionName.prototype.constructor
,因为它们都包含上面的函数定义。
我想我只想解释函数如何在JavaScript中用作对象以及它与原型继承的关系。这是一个广泛的问题,因此主要是为了凿下来,我想知道为什么和当函数的定义被隐式设置为其构造函数时。我想这与支持new functionName()
对象构造范例有关。
答案 0 :(得分:1)
为什么以及何时将函数的定义隐式设置为其构造函数
这不是正在发生的事情。你误解了函数prototype
属性的目的。
JavaScript中的任何函数都可以是构造函数。 A"构造函数"只是一个用new
调用的普通函数,例如new foo()
。
当使用new
调用函数时,该函数返回一个新创建的对象,其原型链以函数的prototype
属性开头。对象的__proto__
属性(或ECMAScript术语中的[[Prototype]]
内部属性)设置为构造函数的prototype
属性。
function Boat() { }
var titanic = new Boat();
console.log(titanic.__proto__ == Boat.prototype); // true
由于函数可以随时用作new
的构造函数,因此每个函数必须具有prototype
属性,以便构造的实例用作其原型链的开头。
实例的constructor
属性用于帮助该实例识别哪个构造函数创建了它。为了实现这一点,该实例具有从其原型链继承的constructor
属性,该属性链设置为以构造函数的prototype
属性开头。每次创建一个函数对象时,它都会提供一个prototype
属性,而prototype
属性的属性设置为constructor
。
function Boat() { }
var titanic = new Boat();
// what constructor function made this instance? The Boat function did
console.log(titanic.constructor == Boat);
// does titanic have its own `constructor` property? no, it does not
console.log(titanic.hasOwnProperty("constructor") == false);
// the `constructor` property is inherited from the prototype chain
console.log(titanic.__proto__.constructor == Boat);
// titanic's prototype chain begins with `Boat.prototype`
console.log(titanic.__proto__ == Boat.prototype);
// these are the same
console.log(titanic.__proto__.constructor == Boat.prototype.constructor);
// these are also the same
console.log(titanic.constructor == Boat.prototype.constructor);
ES5 13.2, Creating Function Objects,步骤16到18:
中描述了此行为
- 创建一个新的本机ECMAScript对象,让 F 成为该对象。
- 按照8.12中的说明设置 F 的[[Get]]除外的所有内部方法。
- 将 F 的[[Class]]内部属性设置为"
Function
"。- 将 F 的[[Prototype]]内部属性设置为15.3.3.1中指定的标准内置函数原型对象。
醇>...
- 让 proto 是创建一个新对象的结果,该对象将由表达式
new Object()
构造,其中Object
是具有该名称的标准内置构造函数。 / LI>- 使用参数"
constructor
",属性描述符{[[Value]]: F调用 proto 的[[DefineOwnProperty]]内部方法,...} ...- 使用参数"
醇>prototype
",属性描述符{[[Value]]: proto ,调用F的[[DefineOwnProperty]]内部方法。 。} ...
答案 1 :(得分:0)
JavaScript只有一个构造 - 它们是 对象 。每个对象通过其原型链接到另一个对象。当您调用函数属性时,JavaScript将查看对象的原型,父对象的原型等,直到找到您要查找的属性。原型搜索的最后一行就像调用toString()一样,它将搜索它,除非你重写了toString()属性,否则它将在Object.prototype中找到toString()。
声明函数时,解释器会创建一个新的函数对象并填充prototype属性。注意:原型的默认值是具有属性构造函数的对象。
function functionName() {}
var newFunction = new functionName();
newFunction.hasOwnProperty('constructor') //false
newFunction.prototype.hasOwnProperty('constructor') //true as you noted above