在下面的代码中,我实例化一个对象,它以两种完全不同的方式继承属性。
function C(){
this.k1 = "v1";
}
C.prototype.k2 = "v2";
var o = new C;
第一个(k1)似乎附加到实例化的对象(o)作为“自己的”对象。属性,第二个(k2)不附加到实例化对象中的任何内容,但似乎只是通过_ _ proto _ _属性(或[[prototype]]访问它的值。在某种程度上,似乎第一种方式类似于(在每个计算中)制作一个'副本'您的桌面上的文件,而第二种方式类似于制作别名'你桌面上的一个文件,当然,在这个比喻中,我是一个文件'类似于'属性'。
我想知道这是否是想象正在发生什么的正确方法,如果是这样,使用一种方法比另一种方法有什么好处和缺点。我假设使用prototype属性可以节省内存,因为它不会强制新实例化的对象(o)将密钥(k1)作为一个“拥有”的对象。财产,但也许我错了。
为什么有人会选择一种方法而不是另一种?
答案 0 :(得分:2)
我想知道这是否是想象正在发生的事情的正确方法
是
为什么有人会选择一种方法而不是另一种?
.prototype
这对于方法(具有动态this
绑定)
this
区分实例的数据需要自己的属性。
答案 1 :(得分:2)
将原型视为继承的原型。在经典的OOP世界中,它几乎就像一个父类。
使用原型的优点是,对于C
不自定义k2
的实例,内存中只存储一个值。但是,如果在实例上设置属性,则直接在对象中创建一个新属性(hasOwnProperty
将返回true)。
缺点是所有读取代码的人都可能不清楚如何设置该值。
另外,请记住,如果默认值没有意义,并且您总是需要计算它,那么将它放在原型中就没什么意义了。
仅供参考,这就是为什么你经常会看到通过其原型绑定到对象的方法,因为它们只是定义代码并且通常是无状态的。
function C() {
this.blah = function () {
return 1;
};
// other stuff
}
var a = new C();
var b = new C();
你在内存中有2个名为blah的函数,而不是1。
对战:
function C() {
// other stuff
}
C.prototype.blah = function () {
return 1;
};
var a = new C();
var b = new C();
现在你在内存中只有一个blah
函数,绑定到2个独立的对象。