JavaScript原型仅限于函数?
o、 原型={…} 仅当o是函数时才起作用。 假设我有以下代码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]]属性,并且只有使用构造函数调用它时的运算
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);