我正在尝试创建2个正弦波并将它们组合在一起以创建第三个。我可以添加它们并将结果输出到控制台,但每当我尝试将此值放入数组时,我都会收到错误:
“无法读取未定义的属性'1'
谁能解释我哪里出错了? Jsfiddle:http://jsfiddle.net/YJqZz/
d1 = [];
d2 = [];
d3 = [];
// Sample the sine function
for (i = 0; i < 2 * Math.PI; i += 0.02) {
d1.push([i, 15+Math.sin(5*i)]);
d2.push([i, 10+Math.sin(4*i)]);
console.log(d1[i][1] + d2[i][1]);
d = d1[i][1] + d2[i][1];
console.log(d);
d3.push([i,d]);
}
答案 0 :(得分:4)
要访问dX
中的最后一个元素,请使用dx[dX.length - 1]
。
你的i
浮在这里(0.02)。该值不是整数,而是转换为字符串。然后,Array对象被解释为常规对象(一种地图)。对象中没有键"0.02"
,因此dX["0.02"]
的计算结果为undefined
。您无法访问undefined
,因此无法访问。
答案 1 :(得分:4)
您尝试使用双精度访问数组中的元素,因为您的循环增加0.02
。当你按下时,数组的键被设置为整数,所以这个方法不起作用。
我重构了你的代码以改为使用Objects: http://jsfiddle.net/YJqZz/2/
d1 = {};
d2 = {};
d3 = {};
// Sample the sine function
for (i = 0; i < 2 * Math.PI; i += 0.02) {
d1[i] = [i, 15+Math.sin(5*i)];
d2[i] = [i, 10+Math.sin(4*i)];
console.log(d1[i][1] + d2[i][1]);
d = d1[i][1] + d2[i][1];
console.log(d);
d3[i] = [i,d];
}
答案 2 :(得分:1)
此代码存在很多问题。
首先,在这样的循环中添加浮点数会增加浮点格式的二进制错误,直到它们在输出中变得明显。尝试运行此代码:
var a = [];
for (var i = 0; i < 2 * Math.PI; i += 0.02)
a.push(i);
$('#output').html(a.join('<br/>'));
http://jsfiddle.net/b9chris/AwT5c/
查看它生成的值。它可能不是你所期望的。那些疯狂的数字是浮点数存储方式的结果 - 小数部分存储为二进制小数,所以1/2 + 1/4 + 1/8 + .... 0.02不能以这种格式精确表示,因此系统将其近似,然后在返回时将值舍入为10的十进制小数,覆盖在捏造的基础值上。但是增加是以二进制形式完成的,最终近似值加起来并揭示了这个问题。
解决方案是用整数循环并尽可能晚地划分:
http://jsfiddle.net/b9chris/AwT5c/1/
其次,循环条件包括始终返回相同结果的操作。这会浪费CPU时间 - for循环将不断重新计算2 * Math.PI的值,以便在每个循环中获得完全相同的结果。您可以通过将其存储在变量中并对其运行循环来解决此问题。
您可能无法理解Array.push()的工作原理。您将一个值传递给push,它会自动将其分配给数组中的下一个索引。所以这个,在一个包含1个值的数组上运行:
a.push([5, 10]);
在索引1(而不是5)处添加值,该值本身就是一个2项数组[5, 10]
。那么你在做什么:
d1.push([i, 1]);
var d = d1[i][1];
例如,您在索引0处添加了一个值,然后尝试在索引0.02处将其恢复。由于您的目标是通过索引直接访问它们,因此使用推送并不安全,然后假设索引与循环计数器中的内容匹配(例如,如果数组已经添加了值,该怎么办? )。而是直接按索引分配,这在Javascript中是允许的。
最后,您应该避免将所有内容转储到全局范围内 - 使用var关键字将它们作为本地范围。
var d1 = [];
var d2 = [];
var d3 = [];
var inverseStep = 50; // 1 / .02
var l = 2 * Math.PI * inverseStep;
for (var i = 0; i < l; i++) {
var ix = i / inverseStep;
d1[i] = [ix, 15+Math.sin(5*ix)];
d2[i] = [ix, 10+Math.sin(4*ix)];
var d = d1[i][1] + d2[i][1];
d3[i] = [ix, d];
}
$('#output').html(d3.join('<br/>'));