【问题标题】:JavaScript function Prototype: Object, Function, or Both?JavaScript 函数原型:对象、函数还是两者?
【发布时间】:2014-01-23 21:22:34
【问题描述】:

JavaScript 函数原型链中的 Function 在哪里?

工作示例:在 Chrome 的控制台中,我创建了以下函数:

> var f = function() { alert(1); }

使用f() 正确调用会产生数字 1 的警报。使用以下控制台语句检查函数后:

> console.dir(f)

注意原型是如何被列为对象的,以键/值对prototype: Object的形式,这意味着函数f直接继承自对象。很公平; JavaScript 中的数组和其他实体也继承自 Object。

冲突源于以下观察。输入以下命令:

f instanceof Function

这导致true。

据我了解,用户创建的函数继承自 Function 对象,而 Function 对象又继承自 Object;但是,对于我的生活,我无法通过检查 f 的原型链来找到它。

Function 在函数 f 的原型链中的什么位置?

tyvm

【问题讨论】:

    标签: javascript function object prototype


    【解决方案1】:

    函数 f 的原型链中的函数在哪里?

    Function 本身不是,它是Function.prototype。它应该在函数f的“下方”:

             f
             |
             v
     Function.prototype
             |
             v
      Object.prototype
             |
             v
            null
    

    注意原型是如何被列为对象的,以键/值对原型的形式:对象

    您所看到的f 的.prototype 属性是函数自己的原型对象 - 假设f 将是一个构造函数,那么所有new f 实例将继承自f.prototype。

    表示函数 f 直接继承自 Object。

    不。公共.prototype 属性不得与内部原型链(通常表示为[[prototype]] 内部属性)混淆。您可以使用Object.getPrototypeOf 访问原型链。更多信息请访问__proto__ VS. prototype in JavaScript,可能是Why functions prototype is chained repeatedly? 或http://eloquentjavascript.net/chapter8.html。

    【讨论】:

    • 您的图表正是我理解 JavaScript 继承的方式......但控制台日志语句不对应! 1. Function.prototype 未在函数“f”“下方”列出 2. Object.getPrototypeOf(f) 产生function Empty() {}。 o.o?这在哪里适合拼图? 3. 如果您愿意推荐一个链接以进一步阅读有关公共和内部原型属性的链接,那将非常有帮助。
    • 您还会发现使用 (function Empty() {}).isPrototypeOf(f) 会产生错误,尽管它首先告诉您原型是这样的。跨度>
    • @kmiklas: 1. 我不知道您使用的是哪个浏览器(哪个控制台)。 console.dir 至少显示了自己的属性(包括 .prototype),可能是可扩展列表中的原型链对象。如果没有,请改用console.log(f)。 2. 是的,Object.getPrototypeOf(f) === Function.prototype 将显示为function Empty() {} - 请注意,当您粘贴它时,您正在创建另一个函数。试试Function.prototype.isPrototypeOf(f) :-)
    • @kmiklas: f 不继承自 Function (f instanceof Function),它是 Function 的一个实例。我认为这是你困惑的根源。
    【解决方案2】:

    对于来此线程寻找信息的人,我将从头开始。

    kmiklas 可以忽略所有内容,直接跳转到最后的链接。其他对 Javascript 不确定的人应继续阅读下文。

    //从头开始。

    在 JavaScript 中,几乎所有东西都是对象。甚至原始数据类型(null 和 undefined 除外)也可以视为对象。

    布尔值可以是对象或被视为对象的原始数据 数字可以是对象或被视为对象的原始数据 字符串也是对象或被视为对象的原始数据 日期总是对象 数学和正则表达式始终是对象 数组总是对象 甚至函数也总是对象

    JavaScript 是一种面向对象的语言,但 JavaScript 不使用类。

    在 JavaScript 中,您无需定义类并从这些类创建对象(就像在大多数其他面向对象的语言中一样)。

    JavaScript 是基于原型的,而不是基于类的。

    Javascript 中的每个对象都有一个原型。当消息到达一个对象时,JavaScript 将首先尝试在该对象中查找属性,如果找不到,则将消息发送到对象的原型,依此类推。这就像基于类的语言中的单父继承一样。

    原型继承链可以随心所欲。但总的来说,制作长链并不是一个好主意,因为您的代码可能难以理解和维护。

    -------> More info on Prototypes and Javascript (VERY USEFUL!!!) <-------

    【讨论】:

    • 感谢您的贡献,但您不应发布与问题无关的内容。想象一下消失了,剩下的就是link only answer。您可能已经通过链接对问题发表了评论,或者在您的答案中包含了该博客文章的相关部分(作为引用)
    【解决方案3】:

    我认为您误解了 javascript 原型链。在控制台中试试这个:

    function AnObject(){
    
    }
    
    AnObject.prototype = {
        aMethod: function() {
            return "hi";
        }
    }
    

    new AnObject().aMethod() 现在返回“hi”。

    您看到 AnObject.prototype 无法返回 AnObject 祖先:实际上,它是要被要在 AnObject 实例上复制的方法覆盖。

    AnObject.prototype 现在返回

    {
       aMethod: function() {
            return "hi";
       }
    }
    

    如果你想知道AnObject函数的类型,你可以使用AnObject.constructor,你会得到function Function() { [native code] }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 2016-05-13
      • 1970-01-01
      • 1970-01-01
      • 2016-08-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多