Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/416.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 数组键编号和";“数字”;意外地被认为是相同的_Javascript_Arrays_Type Conversion - Fatal编程技术网

Javascript 数组键编号和";“数字”;意外地被认为是相同的

Javascript 数组键编号和";“数字”;意外地被认为是相同的,javascript,arrays,type-conversion,Javascript,Arrays,Type Conversion,我一直在玩javascript数组,我遇到了一些不一致的地方,希望有人能给我解释一下 让我们从以下内容开始: var myArray = [1, 2, 3, 4, 5]; document.write("Length: " + myArray.length + "<br />"); for( var i in myArray){ document.write( "myArray[" + i + "] = " + myArray[i] + "<br />"); }

我一直在玩javascript数组,我遇到了一些不一致的地方,希望有人能给我解释一下

让我们从以下内容开始:


var myArray = [1, 2, 3, 4, 5];
document.write("Length: " + myArray.length + "<br />");
for( var i in myArray){
   document.write( "myArray[" + i + "] = " + myArray[i] + "<br />");
}
document.write(myArray.join(", ") + "<br /><br />");

var myArray=[1,2,3,4,5];
文件。写入(“长度:“+myArray.Length+”
); for(myArray中的变量i){ 文件。写入(“myArray[“+i+”]=“+myArray[i]+”
”; } document.write(myArray.join(“,”+“

”);
长度:5 myArray[0]=1 myArray[1]=2 myArray[2]=3 myArray[3]=4 myArray[4]=5 1, 2, 3, 4, 5 这段代码没有什么特别之处,但我知道javascript数组是一个对象,因此属性可能会添加到数组中,这些属性添加到数组中的方式对我来说似乎不一致

在继续之前,让我注意一下如何在javascript中将字符串值转换为数字值

  • 非空字符串->字符串或NaN的数值

  • 空字符串->0

因此,由于javascript数组是一个对象,以下内容是合法的:


myArray[“某物”]=“某物”;
myArray[“”]=“空字符串”;
myArray[“4”]=“四”

for(myArray中的变量i){ 文件。写入(“myArray[“+i+”]=“+myArray[i]+”
”; } document.write(myArray.join(“,”+“

”);

长度:5 myArray[0]=1 myArray[1]=2 myArray[2]=3 myArray[3]=4 myArray[4]=4 myArray[某物]=某物 myArray[]=空字符串 1,2,3,4,4 输出是意外的

设置属性myArray[“4”]时,非空字符串“4”被转换为其数值,这似乎是正确的。但是,空字符串“”未转换为其数值0,它被视为空字符串。此外,非空字符串“something”不会转换为其数值NaN,它被视为字符串。那是哪一个呢?myArray[]中的语句是数值上下文还是字符串上下文


另外,为什么myArray.length和myArray.join(“,”)中不包含myArray的两个非数字属性?

JavaScript数组的键实际上是字符串。有关任意键的映射类型的详细信息和实现,请选中


澄清并补充Jason发布的内容:JavaScript数组是对象。对象具有属性。属性名称是字符串值。因此,数组索引也会在发生任何事情之前转换为字符串。如果满足以下条件(ECMA-262,15.4),则属性名P将被视为数组索引(即将调用特殊数组魔术):

ToString(ToUint32(p))等于p,而ToUint32(p)不等于2^32− 一,

数字索引将转换为字符串(而不是相反的方式)很容易验证:

var array = [];
array[1] = 'foo';
array['1'] = 'bar';
array['+1'] = 'baz';
document.writeln(array[1]); // outputs bar

此外,在循环中使用“
for..in
循环”来迭代数组条目也是一种不好的做法——如果有人弄乱了一些原型,您可能会得到意想不到的结果(而且速度也不是很快)。将标准的
用于(var i=0;i

(编辑:以下内容不太正确)

JavaScript对象的键实际上是字符串。Javascript数组本身具有数字索引。如果您使用可以解释为非负整数的索引存储某些内容,它将尝试这样做。如果存储的索引不是非负整数(例如,它是字母数字、负数或带小数的浮点数),它将在数组索引存储中失败,并默认为对象(数组的基类)存储,然后将参数转换为字符串并按字符串索引存储--但是这些存储的属性不被数组类看到,因此对其方法/属性(长度、连接、切片、拼接、推送、弹出等)不可见


编辑:上面的说法不太正确(如Christopher的foo/bar/baz示例所示)。实际上,根据的实际存储索引是字符串,但如果它们是有效的数组索引(非负整数),那么数组对象的
[[Put]]]
方法是特殊的,它使这些特定值对数组的“array ish”方法可见。

我不同意Christoph的说法“数组索引转换为字符串”

首先,我认为这取决于实现……我认为(好的)实现者会优化阵列访问,有一些聪明的方法可以做到这一点

事实上,我做了一个小测试,虽然它和大多数微基准测试一样好(即不是超级可靠),但它很有趣:

result = ""
var x;

var trueArray = []
var startTime = new Date();
for (var i = 0; i < 100000; i++)
{
  x = "i" + i; // To do the same operations
  trueArray[i] = 1;
}
var endTime = new Date();
result += "With array: " + (endTime - startTime) + "\n";

var sArray = []
var startTime = new Date();
for (var i = 0; i < 100000; i++)
{
  x = "" + i;
  sArray[x] = 1;
}
var endTime = new Date();
result += "With s array: " + (endTime - startTime) + "\n";

var objArray = {}
var startTime = new Date();
for (var i = 0; i < 100000; i++)
{
  x = "i" + i;
  objArray[x] = 1;
}
var endTime = new Date();
result += "With object(i): " + (endTime - startTime) + "\n";

var sobjArray = {}
var startTime = new Date();
for (var i = 0; i < 100000; i++)
{
  x = "" + i;
  sobjArray[x] = 1;
}
var endTime = new Date();
result += "With s object: " + (endTime - startTime) + "\n";

var iobjArray = {}
var startTime = new Date();
for (var i = 0; i < 100000; i++)
{
  x = "" + i;
  iobjArray[i] = 1;
}
var endTime = new Date();
result += "With i object: " + (endTime - startTime) + "\n";


// Then display result
result=“”
var x;
var trueArray=[]
var startTime=新日期();
对于(变量i=0;i<100000;i++)
{
x=“i”+i;//执行相同的操作
trueArray[i]=1;
}
var endTime=新日期();
结果+=”和数组:“+(结束时间-开始时间)+”\n”;
var sArray=[]
var startTime=新日期();
对于(变量i=0;i<100000;i++)
{
x=”“+i;
sArray[x]=1;
}
var endTime=新日期();
带s数组的结果+=“+(结束时间-开始时间)+”\n”;
var objArray={}
var startTime=新日期();
对于(变量i=0;i<100000;i++)
{
x=“i”+i;
objArray[x]=1;
}
var endTime=新日期();
结果+=“与对象(i):”+(结束时间-开始时间)+“\n”;
var sobjArray={}
var startTime=新日期();
对于(变量i=0;i<100000;i++)
{
x=”“+i;
sobjArray[x]=1;
}
var endTime=新日期();
结果+=“与s对象:”+(结束时间-开始时间)+“\n”;
var iobjArray={}
var startTime=新日期();
对于(变量i=0;i<100000;i++)
{
x=”“+i;
iobjArray[i]=1;
}
var endTime=新日期();
结果+=“带i对象:”+(endTime-startTime)+“\n”;
//然后显示结果
在IE6上,我得到:With array:1453 With object:3547
在FF3.0上,我得到:With array:83 With object:226
在Safari 3.1上,我得到:With array:140 With object:313
在Opera9.26上,由于某种原因,我没有得到结果,但是如果我减少到循环数的十分之一,我会得到结果 Length: 5 myArray[0] = 1 myArray[1] = 2 myArray[2] = 3 myArray[3] = 4 myArray[4] = four myArray[someThing] = someThing myArray[] = Empty String 1, 2, 3, 4, four
var array = [];
array[1] = 'foo';
array['1'] = 'bar';
array['+1'] = 'baz';
document.writeln(array[1]); // outputs bar
result = ""
var x;

var trueArray = []
var startTime = new Date();
for (var i = 0; i < 100000; i++)
{
  x = "i" + i; // To do the same operations
  trueArray[i] = 1;
}
var endTime = new Date();
result += "With array: " + (endTime - startTime) + "\n";

var sArray = []
var startTime = new Date();
for (var i = 0; i < 100000; i++)
{
  x = "" + i;
  sArray[x] = 1;
}
var endTime = new Date();
result += "With s array: " + (endTime - startTime) + "\n";

var objArray = {}
var startTime = new Date();
for (var i = 0; i < 100000; i++)
{
  x = "i" + i;
  objArray[x] = 1;
}
var endTime = new Date();
result += "With object(i): " + (endTime - startTime) + "\n";

var sobjArray = {}
var startTime = new Date();
for (var i = 0; i < 100000; i++)
{
  x = "" + i;
  sobjArray[x] = 1;
}
var endTime = new Date();
result += "With s object: " + (endTime - startTime) + "\n";

var iobjArray = {}
var startTime = new Date();
for (var i = 0; i < 100000; i++)
{
  x = "" + i;
  iobjArray[i] = 1;
}
var endTime = new Date();
result += "With i object: " + (endTime - startTime) + "\n";


// Then display result
myArray["someThing"] = "someThing";
myArray.someThing = "someThing";
var start, end, count = 1000000;

var obj = {},
    array = [];

start = new Date;
for(var i = count; i--; )
    array[i] = i;
end = new Date;
document.writeln(Number(end) - Number(start));

start = new Date;
for(var i = count; i--; )
    obj[i] = i;
end = new Date;
document.writeln(Number(end) - Number(start));