【问题标题】:[[Prototype]] vs prototype: ..what is the difference? (MyCons.__proto__ === MyCons.prototype) equals FALSE[[Prototype]] vs原型:..有什么区别? (MyCons.__proto__ === MyCons.prototype) 等于 FALSE
【发布时间】:2012-03-16 03:36:41
【问题描述】:

这里好像有区别……

假设我们有function MyConstructor() {}

MyConstructor 的[[Prototype]]Function.prototype不是 MyConstructor.prototype.

用其他(non-standard/"console.log-able") 的话来说:
MyConstructor.__ proto__ 不是 MyConstructor 的MyConstructor.prototype

试试这个:

function MyConstructor() {};
(MyConstructor.__proto__ === MyConstructor.prototype); //false?! why?

为什么会这样?有人可以向我解释一下区别吗?

【问题讨论】:

标签: javascript prototype prototype-programming


【解决方案1】:

这样想。 MyConstructor是一个函数对象,所以它是由Function创建的;因此它的[[Prototype]](或__proto__)与Function.prototype相同。

同样,var myObj = new MyConstructor() 创建一个对象myObj,其[[Prototype]]MyConstructor.prototype 相同。

换句话说,函数有一个prototype 属性,当你调用带有new 的函数时,它们将构造一个具有与构造函数的prototype 属性相同的[[Prototype]] 的对象......但是函数的prototype 属性与其[[Prototype]](或__proto__)属性不同,因为函数遵循与其他对象相同的规则,并从构造它的函数获取其内部[[Prototype]] 属性(其中总是Function,顺便说一下)。


为了进一步解释,[[Prototype]]prototype 具有完全不同的目的。 [[Prototype]] 用于解析对象的属性。如果对象没有属性,则检查其[[Prototype]],然后检查该对象的[[Prototype]],以此类推,直到找到属性或到达原型链的末尾。

相比之下,prototype 是您将[[Prototype]] 属性分配给对象的机制,因为除了使用非标准__proto__ 属性之外,您无法直接访问它们。

由于函数是对象,它们既有[[Prototype]] 内部属性,用于像普通对象一样解析属性,也有prototype 属性,它被分配为由函数构造的新对象的[[Prototype]]

【讨论】:

    【解决方案2】:

    这段代码会显示得很清楚:

    var obj = {};
    var arr = [];
    var fun = function() {};    
    
    A:     
    console.log(obj.prototype);
    console.log(arr.prototype);
    console.log(fun.prototype);
    
    B:
    console.log(arr.__proto__);
    console.log(fun.__proto__);
    
    C:
    console.log(obj.__proto__);
    console.log(arr.__proto__.__proto__);
    console.log(fun.__proto__.__proto__);
    console.log(fun.prototype.__proto__);

    chrome 控制台是:

    那个意思:

    A.在 JavaScript 中,'prototype' 是仅存在于函数中的特殊对象 - 用于制作函数构造函数(对于您的问题 - 这就是为什么 'prototype' 它不等于 'proto')。

    B.数组和函数具有它们自己的“proto”以及它们内置在 JavaScript 中的所有属性和方法。

    C. JavaScript 中真正在它们内部的所有东西都是对象,因此函数的 'prototype.proto' 或函数的 'proto.proto' 和数组都等于对象的“proto”。

    【讨论】:

    • 等等,该代码确实有效。如中,“A:”和“B:”行有效。我只是在控制台中执行了“a:5”,它打印了“5”,但没有创建“a”全局变量。我糊涂了。通常你在对象字面量中使用这些,但是它们之外的用途是什么?您不能将它们用作标签并“转到”它们或任何东西,所以...你知道吗?
    • 所以,在找到正确的搜索方法后,我终于想通了,这实际上是与此结果匹配的短语:stackoverflow.com/questions/34190256/…。因此,看起来 Javascript 具有仅充当 goto 的 CONTINUE 语句的标签。老实说,在我看来,这是 goto 唯一有效的用途之一。它不再像人们所说的那样使用像 C# 这样的现代语言,因为你只能在相同的范围内执行它(因此阻止了 99.9% 的意大利面条代码)。只是总有更好的方法。
    • 最后一件事,似乎有人在 javascript 中“添加”了完整的“goto”功能。它可以工作,你只需要执行 "[lbl] a:" 而不是 a: 然后通过 gotojs 运行它以将其转换为输出。如果它在您网站上的脚本标记中,您可以将它们全部自动解析(或使用特定的“类型”,如“text/gotojs”)。很有趣。
    【解决方案3】:

    受到另一个答案的启发,并完成它:

    var obj = {name: 'Ali'};
    var arr = [1, 2, 3];
    var date = new Date();
    var func = function(){console.log('Hi!')};
    var arrowFunc = ()=>{};
    
    obj.prototype === undefined;
    arr.prototype === undefined;
    date.prototype === undefined;
    func.prototype != undefined;
    func.hasOwnProperty('prototype') === true;
    arrowFunc.prototype === undefined;
    arrowFunc.hasOwnProperty('prototype') === false;
    
    obj.__proto__ === Object.prototype;
    arr.__proto__ === Array.prototype;
    date.__proto__ === Date.prototype;
    func.__proto__ === Function.prototype;
    arrowFunc.__proto__ === Function.prototype;
    
    Array.prototype.__proto__ === Object.prototype;
    Date.prototype.__proto__ === Object.prototype;
    Function.prototype.__proto__ === Object.prototype;
    
    Object.prototype__proto__ === undefined;
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-29
      • 1970-01-01
      • 2015-09-29
      • 2012-04-15
      • 1970-01-01
      • 2019-11-29
      • 1970-01-01
      相关资源
      最近更新 更多