带剔除的对象继承 属性
Object inheritance with a knockout property
我有如下js继承示例:
function Fruit(){
this.who = function(){ console.dir(this.fruitName); }
}
Fruit.prototype.fruitName = "I am a fruit";
function Orange(){
Fruit.call();
this.fruitName = "I am an orange";
}
Orange.prototype = new Fruit();
Orange.prototype.constructor = Orange;
function Apple(){
Fruit.call();
this.fruitName = "I am an apple";
}
Apple.prototype = new Fruit();
Apple.prototype.constructor = Orange;
var orange = new Orange();
var apple = new Apple();
orange.who();
apple.who();
上面的代码输出:
I am an orange
I am an apple
哪个是正确的。
现在,将 fruitName
更改为可观察到的淘汰赛会产生意想不到的结果:
function Fruit(){
this.who = function(){ console.dir(this.fruitName()); }
}
Fruit.prototype.fruitName = ko.observable("I am a fruit");
function Orange(){
Fruit.call();
this.fruitName("I am an orange");
}
Orange.prototype = new Fruit();
Orange.prototype.constructor = Orange;
function Apple(){
Fruit.call();
this.fruitName("I am an apple");
}
Apple.prototype = new Fruit();
Apple.prototype.constructor = Orange;
var orange = new Orange();
var apple = new Apple();
orange.who();
apple.who();
输出:
I am an apple
I am an apple
除非我做错了什么,否则这看起来像是 Knockout 中的错误。
有办法解决这个问题吗?
此处提供完整的 jsfiddle:https://jsfiddle.net/h1go9se2/
怎么回事
原型的想法是它在实例之间共享。函数使用 this
来确保 运行 方法实际影响单个实例。
Knockout observables 是函数,但最好将它们视为值的包装器。
如果你在原型上定义你的可观察对象,这意味着你包装了一个由所有实例共享的值。
在扩展它的任何 class 的构造函数中写入该值将覆盖所有实例的值。
修复
不是在 Fruit
原型上声明 fruitName
,而是在 Fruit
构造函数中定义 属性:
function Fruit(){
this.who = function(){ console.dir(this.fruitName()); }
this.fruitName = ko.observable("I am a fruit");
}
可运行代码段:
function Fruit(){
this.who = function(){ console.dir(this.fruitName()); }
this.fruitName = ko.observable("I am a fruit");
}
function Orange(){
Fruit.call();
this.fruitName("I am an orange");
}
Orange.prototype = new Fruit();
Orange.prototype.constructor = Orange;
function Apple(){
Fruit.call();
this.fruitName("I am an apple");
}
Apple.prototype = new Fruit();
Apple.prototype.constructor = Orange;
var orange = new Orange();
var apple = new Apple();
orange.who();
apple.who();
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
我有如下js继承示例:
function Fruit(){
this.who = function(){ console.dir(this.fruitName); }
}
Fruit.prototype.fruitName = "I am a fruit";
function Orange(){
Fruit.call();
this.fruitName = "I am an orange";
}
Orange.prototype = new Fruit();
Orange.prototype.constructor = Orange;
function Apple(){
Fruit.call();
this.fruitName = "I am an apple";
}
Apple.prototype = new Fruit();
Apple.prototype.constructor = Orange;
var orange = new Orange();
var apple = new Apple();
orange.who();
apple.who();
上面的代码输出:
I am an orange
I am an apple
哪个是正确的。
现在,将 fruitName
更改为可观察到的淘汰赛会产生意想不到的结果:
function Fruit(){
this.who = function(){ console.dir(this.fruitName()); }
}
Fruit.prototype.fruitName = ko.observable("I am a fruit");
function Orange(){
Fruit.call();
this.fruitName("I am an orange");
}
Orange.prototype = new Fruit();
Orange.prototype.constructor = Orange;
function Apple(){
Fruit.call();
this.fruitName("I am an apple");
}
Apple.prototype = new Fruit();
Apple.prototype.constructor = Orange;
var orange = new Orange();
var apple = new Apple();
orange.who();
apple.who();
输出:
I am an apple
I am an apple
除非我做错了什么,否则这看起来像是 Knockout 中的错误。 有办法解决这个问题吗?
此处提供完整的 jsfiddle:https://jsfiddle.net/h1go9se2/
怎么回事
原型的想法是它在实例之间共享。函数使用 this
来确保 运行 方法实际影响单个实例。
Knockout observables 是函数,但最好将它们视为值的包装器。
如果你在原型上定义你的可观察对象,这意味着你包装了一个由所有实例共享的值。
在扩展它的任何 class 的构造函数中写入该值将覆盖所有实例的值。
修复
不是在 Fruit
原型上声明 fruitName
,而是在 Fruit
构造函数中定义 属性:
function Fruit(){
this.who = function(){ console.dir(this.fruitName()); }
this.fruitName = ko.observable("I am a fruit");
}
可运行代码段:
function Fruit(){
this.who = function(){ console.dir(this.fruitName()); }
this.fruitName = ko.observable("I am a fruit");
}
function Orange(){
Fruit.call();
this.fruitName("I am an orange");
}
Orange.prototype = new Fruit();
Orange.prototype.constructor = Orange;
function Apple(){
Fruit.call();
this.fruitName("I am an apple");
}
Apple.prototype = new Fruit();
Apple.prototype.constructor = Orange;
var orange = new Orange();
var apple = new Apple();
orange.who();
apple.who();
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>