我尝试提高我的JavaScript技能。 我不明白为什么(5)有效,(2)返回错误。不一样吗?
a.fn2()//确定
var A = function () {
this.fn = function () { alert(3); }
}
A.prototype = {
fn2: function () { alert(4); }
};
var B =
{
fn: function () { alert(1); }
}
B.prototype = {
fn2: function () { alert(2); }
};
答案 0 :(得分:7)
a
是A
类的一个实例,其中B
是类本身。由于fn2
未定义为静态函数,因此它仅对类B
的实例可用,而不是类B
本身。
如果您想直接使用B
,可以使用:
new B().fn2()
如果您将B
定义为function()
或者,您可以按照定义fn2
fn
答案 1 :(得分:1)
(简单解释)
prototype
属性仅在使用function
作为构造函数时使用(通过使用new
运算符)。 function
创建了prototype
的克隆,并将函数内的this
关键字设置为克隆。克隆上的属性是prototypes
属性的直接引用/指针。
对象文字{}
是替代new Object()
的更强大的表达式,因此从Object.prototype
“继承”属性。
所以:
function ClassLike() {}
ClassLike.prototype = {
foo : "bar"
}
var instance = new ClassLike();
alert( instance.foo ); // bar
可行,因为new
运算符会动态执行某些操作来创建新对象,而不是:
var instance = {
foo : "bar"
}
instance.prototype = {
baz : "foobar"
}
仅为已创建的对象添加另一个属性(原型),并且没有任何进程可以实际分配/更改对象原始原型。
现在,Mozilla已经添加了一个非标准(IE不支持它)的方式来通过__proto__
更改已经实例化的对象原型,并且有一些请求将它添加到ES5(EcmaScript 5)。我不会用它来运行。但它的工作原理如下:
var instance = {};
var parent = {
foo : "bar"
}
instance.__proto__ = parent;
alert( instance.foo ); // bar
更改已经实例化的对象原型的另一种方法是添加到Object
构造函数原型(由于多种原因不建议)。就这样:
var instance = {}; // a more powerful alternative to `new Object()`
Object.prototype.foo = "bar";
alert( instance.foo ); // bar
这一切都是可能的,但这样做是明智的......我会说不,但意见各不相同,我宁愿避免辩论;)
无论如何,只要记住prototype
属性在您new
function
时有用,否则它只会成为实例上的属性。
答案 2 :(得分:0)
你所演示的内容是由我认为是JavaScript中OO的最大问题引起的:原型必须是构造函数的属性而不是对象本身。这意味着如果你有一个可以很容易地定义为对象文字的对象,你仍然需要一个无用的构造函数来定义你的对象的原型。
阅读本文:道格拉斯克罗克福德的Prototypal Inheritance in JavaScript。以下是相关部分:
[...] JavaScript本身存在冲突 关于它的原型性质。在一个 原型系统,对象继承 来自物体。然而,JavaScript, 缺乏执行该操作的操作员 操作。取而代之的是
new
运算符,new f()
生成的运算符 一个继承自的新对象f.prototype
这种间接是 旨在使语言看起来 对经典训练更为熟悉 程序员,但未能做到这一点,因为 我们可以从非常低的意见看出来 Java程序员拥有JavaScript。 JavaScript的构造函数模式确实如此 不吸引古典人群。它 也掩盖了JavaScript的真实性 原型性质。结果,那里 是很少有程序员知道如何 有效地使用该语言。 幸运的是,很容易创建一个 实现true的运算符 原型继承。它是一个 我的工具包中的标准功能,我 强烈推荐给你。
阅读文章,了解一些想法,而不是如何有效地解决你想要做的事情。
答案 3 :(得分:0)
嗯,你的答案很简单。在JavaScript中,只有构造函数有“原型”,即原型属性。对象文字,例如“{}”不。因此,除非您按如下方式更改,否则您的2号将永远不会起作用:
var B = function(){ // the B constructor
return this;
}
B.prototype = {
fn2: function(){ alert(2); }
}