Javascript 构造函数之间的差异
我正在使用TestFirstJavaScript,遇到了一堵混乱的墙。这两个代码片段都通过了测试,但我对这两个解决方案之间的差异或是否存在主要差异感到困惑。总的来说,我相信测试要求我创建的是一个“构造函数”函数 测试用例:Javascript 构造函数之间的差异,javascript,Javascript,我正在使用TestFirstJavaScript,遇到了一堵混乱的墙。这两个代码片段都通过了测试,但我对这两个解决方案之间的差异或是否存在主要差异感到困惑。总的来说,我相信测试要求我创建的是一个“构造函数”函数 测试用例: describe("Calculator", function() { var calculator; beforeEach(function() { calculator = new Calculator(); }); it("initiall
describe("Calculator", function() {
var calculator;
beforeEach(function() {
calculator = new Calculator();
});
it("initially has 0", function() {
expect(calculator.value()).toEqual(0);
});
it("can add a number", function() {
calculator.add(2);
expect(calculator.value()).toEqual(2);
});
it("can add two numbers", function() {
calculator.add(2);
calculator.add(3);
expect(calculator.value()).toEqual(5);
});
it("can add many numbers", function() {
calculator.add(2);
calculator.add(3);
calculator.add(4);
expect(calculator.value()).toEqual(9);
});
it("can subtract a number", function() {
calculator.subtract(2);
expect(calculator.value()).toEqual(-2);
});
it("can add and subtract", function() {
calculator.add(3);
calculator.subtract(2);
expect(calculator.value()).toEqual(1);
});
});
解决方案1:
var Calculator = function(){
this.accumulator = 0;
this.value = function(){
return this.accumulator;
};
this.add = function(operand){
this.accumulator += operand;
};
this.subtract = function(operand){
this.accumulator -= operand;
};
};
解决方案2:
function Calculator() {
this.num = 0;
};
Calculator.prototype = {
value: function() {
return this.num;
},
add: function() {
for (var i = 0; i < arguments.length; i++){
this.num += arguments[i];
}
},
subtract: function() {
for (var i = 0; i < arguments.length; i++){
this.num -= arguments[i];
}
}
};
是calculatorSolOne上的所有属性,还是从Calculator原型继承这些属性
使用解决方案2,属性存储在哪里,我相信对于解决方案2,属性存储在Calculator.prototype上,实际对象上唯一的值是数值(其余属性必须查看Calculator.prototype并从prototype对象获取属性)。在第一种情况下,所有函数和
累加器
将仅启用计算器solone
对象。无论何时创建对象,都会构造新的函数对象。这里不涉及继承。因此,这会导致性能下降,不推荐使用
在第二种情况下,当您创建一个对象时,只有变量
acculator
将启用计算器solone
对象,所有函数将仅在prototype对象中。当您尝试访问它们时,JavaScript会检查原型链,因为它在当前对象中找不到属性。在第一种情况下,当您构建一个新的计算器时,新对象具有新的函数实例。由于每个函数的所有副本都只是逐字复制,这是一种浪费,这就是为什么基于原型的解决方案更可取的原因。关于解决方案2的工作原理,您是正确的:计算器的每个实例都有自己的编号,并且每个成员函数都有一个在所有实例中共享的副本。因为解决方案1中的原型没有属性,如何继承?以下答案的可能重复可能有助于您理解原型和实例特定成员之间的区别:您正在破坏prototype.constructor
属性,方法是设置原型,这样在其他人使用您的代码和期望构造函数指向实际的构造函数。
var calculatorSolOne = new Calculator();