JavaScript原型仅限于函数?

JavaScript原型仅限于函数?,javascript,prototype,function,object,Javascript,Prototype,Function,Object,o、 原型={…} 仅当o是函数时才起作用。 假设我有以下代码 conf = { a: 2, b: 4 }; conf.prototype = { d: 16 } conf.a和conf.b正常并返回正确的值。但是conf.d并没有返回16,而是没有定义。是否有任何解决方案可以将基于原型的泛化应用于这些类型的对象。您混淆了可用于的prototype属性和内部[[prototype]]属性 所有对象都具有此内部[[Prototype]]属性,并且只有使用构造函数调用它时的运算

o、 原型={…} 仅当o是函数时才起作用。 假设我有以下代码

 conf = {
  a: 2,
  b: 4
 };
 conf.prototype = {
  d: 16
 }

conf.a和conf.b正常并返回正确的值。但是conf.d并没有返回16,而是没有定义。是否有任何解决方案可以将基于原型的泛化应用于这些类型的对象。

您混淆了可用于的
prototype
属性和内部
[[prototype]]
属性

所有对象都具有此内部
[[Prototype]]
属性,并且只有使用构造函数调用它时的运算符才允许设置它(通过内部操作)

如果您想通过对象实例实现原型继承(不使用构造函数),Crockford的技术就是您想要的(该方法现在是最近批准的ECMAScript第5版的一部分):

在上述代码中,
conf
将有三个成员,但只有
a
b
将物理存在于其上:

conf.hasOwnProperty('a'); // true 
conf.hasOwnProperty('b'); // true
conf.hasOwnProperty('d'); // false
因为
d
存在于conf
[[Prototype]]
confProto
)上


[]
负责解析在原型链中查找的属性(如果需要)(通过内部方法)。

JavaScript中实际上有两种不同类型的“原型”:

  • 一个是每个对象都具有的“隐藏”链接(让我们使用
    [[Prototype]]
    来表示这个隐藏链接)。默认情况下,对象文字的隐藏链接指向
    对象。原型
    ,函数对象的隐藏链接指向
    函数。原型
    ,数组的隐藏链接指向
    数组。原型
    。这些隐藏的原型链接与名为“prototype”的属性无关。您不能通过添加或修改
    o.prototype
    来更改这些隐藏链接
  • 另一个是所有函数对象自动具有一个名为“
    prototype
    ”的特殊属性。这主要是为了使用构造函数调用模式
  • [[Prototype]]
    用于搜索属性(就像经典层次结构中的父级),每当在对象中找不到属性时,就会搜索其
    [[Prototype]]
    。一种使用场景:假设您想向所有对象添加属性,只需将其添加到
    对象.prototype
    ,该属性将自动应用于所有对象,因为所有对象都以某种方式将
    对象.prototype
    作为其
    [[prototype]]
    链根

    让我们回到函数对象的“
    prototype
    ”属性。它仅在与操作员
    new
    一起使用时有用。以以下代码段为例:

    function F() {} // function declaration
    // F now has a property named "prototype"
    
    var f = new F(); // use "new" operator to create a new function object based on F
    
    上面的
    new F()
    所做的是首先创建一个新的函数对象,将这个新创建的函数对象的
    [[Prototype]]
    (隐藏链接)设置为
    F.Prototype
    ,然后返回新的函数对象。这可能是您已经了解的适用于函数对象的方法

    记得我说过我们不能改变对象的
    [[Prototype]]
    ?嗯,至少不是直接的。Crockford的
    Object.create
    函数就是这样做的,它利用了操作符
    new
    可以帮助我们设置
    [[Prototype]]
    。因此,通过使用
    Object.create
    ,您可以有意识地指出新对象的隐藏链接应该指向的位置。(有点想指出谁是您的父类)

    在您的示例中,
    conf
    是一个对象文本,而
    conf.prototype
    并不是真正有用的。这是另一个采用古典风格的版本:

    function ConfBase() {}
    ConfBase.prototype.d = 16;
    var conf = new ConfBase();
    conf.a = 2;
    conf.b = 4;
    
    document.writeln(conf.a);
    document.writeln(conf.b);
    document.writeln(conf.d);
    

    与@CMS的答案相比,我更喜欢使用
    Object.create
    。但本质上这两种样式使用的是相同的底层机制,只是
    对象。create
    有助于整理它。

    请投票人留下评论好吗?我总是希望改进我的答案:)
    function ConfBase() {}
    ConfBase.prototype.d = 16;
    var conf = new ConfBase();
    conf.a = 2;
    conf.b = 4;
    
    document.writeln(conf.a);
    document.writeln(conf.b);
    document.writeln(conf.d);