Javascript 使用剔除观测值的计算会缩短计算时间
我注意到了一个问题,当我用ko观测值进行一些繁重的计算时 您将在中找到的问题示例 简而言之,我有一个输入字段和一个可观察的“val” 如果我通过脚本(第二种方法)设置一个值,一切都很好。 但是,如果我手动设置一个值(第一种方法),计算时间会膨胀多次 我认为这是一种奇怪的行为,不应该如此。但我找不到问题所在。这是knockoutJS中的问题吗 为了澄清这一点,使用下面的代码,一切都很好Javascript 使用剔除观测值的计算会缩短计算时间,javascript,performance,knockout.js,observable,Javascript,Performance,Knockout.js,Observable,我注意到了一个问题,当我用ko观测值进行一些繁重的计算时 您将在中找到的问题示例 简而言之,我有一个输入字段和一个可观察的“val” 如果我通过脚本(第二种方法)设置一个值,一切都很好。 但是,如果我手动设置一个值(第一种方法),计算时间会膨胀多次 我认为这是一种奇怪的行为,不应该如此。但我找不到问题所在。这是knockoutJS中的问题吗 为了澄清这一点,使用下面的代码,一切都很好 var val = 3.14; for(var sum=0, ii=0; ii > imax; ii++
var val = 3.14;
for(var sum=0, ii=0; ii > imax; ii++)
sum += val
我对这条线的理解
var val = ViewModel.val(); // get current value, e.g. 3.14
应该和我写的一样
var val = 3.14;
这似乎取决于我如何设置可观测值。为什么会这样?我该如何修复它呢?当您键入它是一个字符串时,字符串操作比数字慢 使用
parseFloat
结果也是错误的,具体的字符串和数字不是一回事安德斯是对的!由于javascript需要在每次迭代中进行隐式类型转换,因此该操作的成本更高。您可能听说过
==
运算符,之所以推荐它,是因为它比较类型和值,而不是=
运算符,它只比较值,但对正在比较的值进行隐式类型转换
希望有帮助 问题的根本原因是,当knockout收到输入值更改的通知时,它会从输入字段读取新值,并将其写回可观察值 输入的值是一个字符串,所以这就是KO放入可观察对象的值 如果您希望它是一个数字,那么您需要始终如一地将该值强制为一个数字。执行此操作的最佳方法(IMHO)是通过fn扩展点
ko.observable.fn['asNumber'] = function (defaultValue) {
var target = this;
var interceptor = ko.computed({
read: target,
write: function (value) {
var parsed = parseFloat(value);
var manualNotifyFlag = false;
if (isNaN(parsed)) {
parsed = defaultValue;
manualNotifyFlag = (target() === parsed);
}
if (!manualNotifyFlag) {
target(parsed);
} else {
target.valueHasMutated();
}
}
});
interceptor(target()); // Ensure target is properly initialised.
return interceptor;
}
创建我们的可观察使用以下
val: ko.observable(3.14).asNumber(0)
现在,当设置了可观察对象的值时,无论您是使用数字类型手动进行设置,还是通过元素更改事件使用字符串进行敲除,可观察对象的值都将强制转换为数字
这样可以避免在代码库中到处放置语法浮动
我已经更新了文档以显示这一点
此外,扩展中的parseFloat语句可以很容易地进行改装,以支持任何全球化引擎,再次只需在代码库中的一个位置执行此操作
// Using the jQuery Globalize library from http://github.com/jquery/globalize
var parsed = (typeof (value) === "string" ?
Globalize.parseFloat(value) :
parseFloat(value));
val: ko.observable(3.14).asNumber(0)
// Using the jQuery Globalize library from http://github.com/jquery/globalize
var parsed = (typeof (value) === "string" ?
Globalize.parseFloat(value) :
parseFloat(value));