您能帮助澄清Javascript原型继承方法调用吗?
在这段代码中:您能帮助澄清Javascript原型继承方法调用吗?,javascript,Javascript,在这段代码中: var Fruit = function() {} Fruit.prototype = { color: function () { console.log('Fruit color...') } } var Apple = function () {} Apple.prototype = new Fruit() Apple.prototype.constructor = Apple var a = new Apple() Apple.pr
var Fruit = function() {}
Fruit.prototype = {
color: function () {
console.log('Fruit color...')
}
}
var Apple = function () {}
Apple.prototype = new Fruit()
Apple.prototype.constructor = Apple
var a = new Apple()
Apple.prototype = null // the question!!!
a.color()
当
Apple.prototype
设置为null
时,为什么实例a
仍然可以调用color
方法?在创建实例a
之后,您正在更改Apple.prototype
引用
在此处更改引用不会更改现有实例的引用
你还会发现
var a = new Apple();
Apple.prototype = {}; // some other object
a instanceof Apple; // false
i、 e.因为我们改变了苹果的继承链a
不再被视为苹果
设置Foo.prototype=null
将导致类型错误,如果您试图检查Foo的实例
更改对象的属性不会更改对该对象的引用。e、 g
更改对象本身会更改引用
foo = {hello: 'world'};
foo === bar; // false
或者以更接近于从实例引用原型的方式编写
var Foo = {}, // pseudo constructor
bar = {},
baz = {};
var fizz = {}; // fizz will be our pseudo instance
Foo.bar = bar; // pseudo prototype
fizz.inherit = foo.bar; // pseudo inheritance
Foo.bar = baz; // pseudo new prototype
fizz.inherit === foo.bar; // false, instance inheritance points elsewhere
当前设置继承链的最佳实践不是使用new
,而是使用
如果您需要在Apple实例上调用Fruit
构造函数,您可以这样做
function Apple() {
// this instanceof Apple
Fruit.apply(this);
// ...
}
我们必须了解幕后发生了什么
var a = new Apple();
JavaScript采用基于原型的编程作为其OOP风格。这意味着,它通过克隆以前的对象而不是通过实例化类来创建新对象。给定Gecko和Webkit JavaScript引擎,下面是在上面的“新”语句后面发生的事情:
var a = clone(Apple.prototype); // this is an analogy to memcpy() in C/C++
a.__proto__ = Apple.prototype; // useful for the instanceof checking
a.constructor = Apple; // a function
a.constructor(); // so "this" in the called function means "a"
现在,a.color和Apple.prototype.color都是对地址处相同函数的引用,例如0xABCD,因为值0xABCD是从Apple.prototype复制到a的。因此,调用a.color()将与地址0xABCD关联,它与Apple.prototype无关,因此您可以自由地将Apple.prototype指定为null
事实证明,上面的clone()函数实际上就是众所周知的Object.create()函数。Object.create()还包括uuu proto_uuu属性的赋值。是的,正如我们所知,如果我们添加Apple.prototype
一些方法,例如Apple.prototype.嗅觉=function(){…}
,它将更改现有实例。但是我们改变了苹果的prototype,will不会改变实例。实例和Apple.prototype
引用相同的对象,那么当更改Apple.prototype
值不会影响对象,也不会影响实例?@huang.xinghui-向原型添加方法不会更改实例,该方法通过[[prototype]]提供给实例
chain。也许读过一些关于属性解析和原型链的文章。@RobG你可能会误解,我在setApple.prototype
到null
之前添加了这个方法。像这样var a=newapple();Apple.prototype.smose=function(){console.log('Apple-smose…');Apple.prototype=null//这个问题!!!a、 嗅觉()
它不克隆原型,而是存储对原型的引用。(只要引用存在,它就不会被GC’d,因此即使原始引用被销毁,它也会保留)
var a = new Apple();
var a = clone(Apple.prototype); // this is an analogy to memcpy() in C/C++
a.__proto__ = Apple.prototype; // useful for the instanceof checking
a.constructor = Apple; // a function
a.constructor(); // so "this" in the called function means "a"