在这段代码中:
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()
解决方法
在创建实例a后,您将更改Apple.prototype引用.
此处更改引用不会更改现有实例的引用.
你也会发现
var a = new Apple(); Apple.prototype = {}; // some other object a instanceof Apple; // false
即因为我们已经改变了Apple的继承链,因此不再被视为Apple.
如果您尝试进行Foo检查实例,设置Foo.prototype = null将导致TypeError
更改Object的属性不会更改对该Object的引用.例如
var foo = {},bar = foo; foo.hello = 'world'; foo === bar; // true
更改对象本身会更改引用
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,而是使用Object.create
Apple.prototype = Object.create(Fruit.prototype);
如果你需要在Apple实例上调用Fruit构造函数,你会这样做
function Apple() { // this instanceof Apple Fruit.apply(this); // ... }