2012-08-15 77 views
1

这个问题实际上是另一个question的结果,为此我做了一些实验,结果让我更加困惑。我期待着解释内部实际发生的答案。JavaScript变量赋值令人惊讶

我曾尝试是,

我一直以此为基础估计,因为我得到了一些明确的解释 here

var a = []; 
a['a1'] = []; 
a['a2'] = []; 

console.log(a); // [] 
console.log(a['a1']); // [] 
console.log(a['a2']); // [] 

TEST 1

这让我感到困惑很多,因为它打印b[0]a,并且可以访问length财产,我以为var b可以被视为一个字符数组,因此我试图分配另一个值,但最终没有成功。从基本假设,如果这个可以被视为一个char数组(更一般地作为一个数组),分配应该是成功的。它打破了基本假设。

var b = 'abcd'; 
b['b1'] = []; 

console.log(b); // abcd 
console.log(b.length); // 4 
console.log(b['b1']); // undefined 

TEST 2

但是,如果我创建这样的分配是发生了,

var bb = ['a', 'b', 'c', 'd']; 
bb[4] = []; 

console.log(bb); // ["a", "b", "c", "d", []] 
console.log(bb.length); // 4 
console.log(bb[0]); // a 
console.log(bb[4]); // [] 

由此,我认为,b[4] = [];可能会成功,但

var b = 'abcd'; 
b[4] = []; 

console.log(b); // abcd 
console.log(b.length); // 4 
console.log(b[4]); // undefined 

我的问题是,为什么这些赋值的行为不同,而变量共享一些共同的功能?

这里是demo

谁能请给我什么实际发生的内部一个明确的解释吗?

额外测试

那么,如果我用数值转让尝试,它的行为完全不同的形成这两个。

var c = 1234; 
c[4] = []; 

console.log(c); //1234 
console.log(c.length); // undefined 
console.log(c[0]); //undefined 
console.log(c[4]); //undefined 
+0

你假定一个字符串是一个字符数组。这不是,所以你从这个假设中得到的任何东西都不会起作用。 – JJJ 2012-08-15 16:26:17

+0

@Juhana完全没有,假设,可以被视为一个字符数组,因为结果混淆。 – 2012-08-15 17:23:21

回答

0

推理

你的 “基础估计” 工程,因为a是一个数组。 “测试2”是您编写的使用数组的唯一其他测试用例,这就是为什么这是唯一可行的其他测试用例。

你似乎认为提供一个方括号表示法并且有一个length方法表明一个对象是一个数组。这不是真的。要测试一个对象是否是一个数组,你可以使用JavaScript的instanceof方法,如下所示:

var a = []; 
var b = 'abcd'; 
var bb = ['a', 'b', 'c', 'd']; 
var c = 1234; 

a instanceof Array // => true 
b instanceof Array // => false 
bb instanceof Array // => true 
c instanceof Array // => false 

注意,这里instanceof Array回报true是因为你预期的行为是对的,因为你正在尝试的案件执行数组操作。


为什么 “测试1” 失败

对于 “测试1”,字符串方括号标记进行串类的charAt功能。给定b = 'abcd',执行b[0]与执行b.charAt(0)相同。它是只读的,只是返回该索引处的字符,即“a”。

查看the Mozilla Developer Network documentation for Strings了解更多详情。


为什么“额外测试”失败

为贵“的额外的测试”,整不提供方括号标记或长度的方法,因此,所有这些调用的失败。

+0

我接受推理,但是我想知道的是,如果'b'或'c'不是一种数组,那么赋值如何成功,甚至不会抛出任何异常。 – 2012-08-15 17:16:51

+0

他们没有失败。虽然文字不提供属性,但是自动实例化的对象也可以。尝试'alert(42 [“构造函数”])'。这些调用并没有失败,只是'Number'实例在数字属性上没有任何有意义的数据。另外,方括号用于索引任何对象,它不是数组的唯一。 – 2012-08-16 09:01:17

1

测试1:b内部是一个字符串,而不是一个数组,这样你就不能分配在b位置的东西。

测试2:偏离它的工作原理,因为现在bb是一个数组。

我的问题是,为什么这些赋值行为不同,而 变量共享一些共同的功能?

因为它们的类型不同。

测试3: c是一个数字,而不是一个数组。

也许你有一些C背景,其中字符串是由空字符(\0)终止的字符数组。在JavaScript中,字符串是内置的int类型,它们的行为与数组不同。乔纳森说,[]运营商只是一个方便的访问特定的字符。这里有一些链接,来看看:

+0

在第二行中有小错字'b'应该是'bb' – 2012-08-16 03:10:14

+0

@sogeek:固定的。谢谢! – davidbuzatto 2012-08-16 13:21:11

0

我想我不跟随你的问题是什么。 Javascript以不同的方式处理字符串,数组和整数。你不应该指望他们以同样的方式行事。也没有像JavaScript中的关联数组到第一个例子可以工作的地方。 a['a1']符号类型实际上只是访问对象属性的一种替代方法,在字符串的上下文中没有意义。

1

当您访问除[]以外的任何对象时,会为您提供一个以正确原型实例化的临时对象(如StringNumber)。您可以像使用其他任何软件一样读取和写入此对象的属性 - 例如,尝试使用alert(3["constructor"])。然而,因为这个对象在任何地方都没有被引用,所以在你完成索引之后它会立即进入垃圾,并且当你下次尝试读取刚设置的属性时,实际上是在访问新的临时对象上的属性,自然是空的。

相关问题