【问题标题】:JavaScript variable assignments behaving surprisinglyJavaScript 变量赋值的行为令人惊讶
【发布时间】:2012-08-11 23:18:00
【问题描述】:

这个问题实际上是另一个question 的结果,为此我做了一些实验,结果让我更加困惑。我期待能解释内部实际发生的事情的答案。

我试过的是,

我将此作为基本假设,因为我得到了一些明确的解释 here,

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

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

测试 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

测试 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   

【问题讨论】:

  • 你假设一个字符串是一个字符数组。事实并非如此,因此您从该假设中得出的任何结果都不能保证有效。
  • @Juhana 根本不可以,假设,可以被视为一个字符数组,因为结果混淆了。

标签: javascript arrays variable-assignment


【解决方案1】:

测试 1: b 在内部是一个字符串,而不是一个数组,所以你不能在 b 位置赋值。

测试 2:当然可以,因为现在 bb 是一个数组。

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

因为它们的类型不同。

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

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

【讨论】:

  • 第二行有一个小错字b应该是bb
【解决方案2】:

推理

您的“基本假设”有效,因为 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


为什么“额外测试”失败

对于您的“额外测试”,整数不提供方括号表示法或长度方法,因此所有这些调用都失败了。

【讨论】:

  • 我接受这个推理,但我想知道的是,如果bc 不是数组类型,那么赋值是如何成功的,甚至没有抛出任何异常。跨度>
  • 他们没有失败。虽然文字不提供属性,但自动实例化的对象可以。试试alert(42["constructor"])。这些调用没有失败,只是Number 实例在数字属性上没有任何有意义的数据。此外,方括号用于索引任何对象,它不是数组独有的。
【解决方案3】:

我想我不明白你的问题是什么。 Javascript 以不同的方式处理字符串、数组和整数。你不应该期望他们以同样的方式行事。此外,JavaScript 中没有关联数组之类的东西可以用于您的第一个示例。 a['a1'] 类型的表示法实际上只是访问对象属性的一种替代方式,在字符串的上下文中没有任何意义。

【讨论】:

    【解决方案4】:

    当您使用[] 访问对象以外的任何对象时,系统会为您提供一个使用正确原型(如StringNumber)实例化的临时对象。您可以像使用任何其他对象一样读取和写入此对象的属性 - 例如尝试alert(3["constructor"])。但是,由于该对象在您完成索引后并没有在任何地方被引用,因此在您下次尝试读取刚刚设置的相同属性时,您实际上是在访问新临时对象上的属性,其中,自然是空的。

    【讨论】:

      猜你喜欢
      • 2019-10-05
      • 1970-01-01
      • 2021-08-20
      • 1970-01-01
      • 1970-01-01
      • 2021-09-28
      • 1970-01-01
      • 2012-07-27
      • 2015-10-19
      相关资源
      最近更新 更多