为什么是functionName()== functionName.prototype.constructor()

时间:2015-05-05 18:10:52

标签: javascript function prototypal-inheritance

我注意到我是否有以下内容:

var functionName = function(){console.log("this is a function!")}

调用functionName等同于functionName.prototype.constructor,因为它们都包含上面的函数定义。

我想我只想解释函数如何在JavaScript中用作对象以及它与原型继承的关系。这是一个广泛的问题,因此主要是为了凿下来,我想知道为什么函数的定义被隐式设置为其构造函数时。我想这与支持new functionName()对象构造范例有关。

2 个答案:

答案 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:

中描述了此行为
  
      
  1. 创建一个新的本机ECMAScript对象,让 F 成为该对象。
  2.   
  3. 按照8.12中的说明设置 F 的[[Get]]除外的所有内部方法。
  4.   
  5. F 的[[Class]]内部属性设置为" Function"。
  6.   
  7. F 的[[Prototype]]内部属性设置为15.3.3.1中指定的标准内置函数原型对象。
  8.         

    ...

         
        
    1. proto 是创建一个新对象的结果,该对象将由表达式new Object()构造,其中Object是具有该名称的标准内置构造函数。 / LI>   
    2. 使用参数" constructor",属性描述符{[[Value]]: F调用 proto 的[[DefineOwnProperty]]内部方法,...} ...
    3.   
    4. 使用参数" prototype",属性描述符{[[Value]]: proto ,调用F的[[DefineOwnProperty]]内部方法。 。} ...
    5.   

答案 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