方括号[]中的键值对是什么意思?

mkH*_*Hun 20 javascript

让我们考虑以下是我的对象:

var n = {"aa":"x","dd":'d'};
Run Code Online (Sandbox Code Playgroud)

我在中使用方括号Object.assign。它给出以下结果。[aa: "x", dd: "d"]。最终的代码是:

var n = {"aa":"x","dd":'d'};
var m = Object.assign([],n);

// result is 
[aa: "x", dd: "d"]
Run Code Online (Sandbox Code Playgroud)

在console.log中__proto__告诉它是Array,如果它是以下代码给出的array,unexpected token error

var v = ["sss":"ddd","ccc":"ddd"]; 
Run Code Online (Sandbox Code Playgroud)

这是什么意思?

在此处输入图片说明

ggo*_*len 18

数组是JS中的对象

JS中的数组是外来对象,因此您可以像其他任何对象一样为它们分配属性。

MDN

数组是类似列表的对象

...

数组不能将字符串用作元素索引(如在关联数组中一样),但必须使用整数。使用括号符号(或点符号)通过非整数设置或访问将不会设置或检索数组列表本身中的元素,而是会设置或访问与该数组的对象属性集合关联的变量。数组的对象属性和数组元素列表是分开的,并且数组的遍历和变异操作无法应用于这些命名属性。

Object.assign 我不知道数组和对象之间的区别,只是简单地将参数2+中的键分配给参数1处的对象。这种行为并不奇怪。

const a = [];
a.foo = 42;
const b = Object.assign([], a);                  // sure, why not?
console.log(typeof a, typeof b, b.foo);          // => object object 42
console.log(Array.isArray(a), Array.isArray(b)); // => true true
Run Code Online (Sandbox Code Playgroud)

var a = ["foo": "bar"]语法不起作用,因为JS数组初始化器遵循与函数调用类似的语法。数组初始值设定项在构造函数上不是语法糖Array,但是它相似之处在于它接受逗号分隔的表达式列表。没有理由认为它的行为应与具有其自身规范的对象文字 var obj = {"foo": "bar"}语法相同。这是一件好事,因为将数组作为键值对象滥用与将函数作为键值对象滥用的做法不尽相同:

const func = () => "hello";
func.foo = 42;
console.log(func.foo, typeof func, func()); // => 42 function hello
Run Code Online (Sandbox Code Playgroud)

MDN关于数组文字的文章中

数组文字是零个或多个表达式的列表,每个表达式代表一个数组元素,并用方括号([])括起来。使用数组文字创建数组时,将使用指定的值作为其元素对其进行初始化,并将其长度设置为指定的参数数。

表达式是“解析为值的任何有效代码单位”。该key: value语法是不是表达式本身,而只初始化语法对象的一部分,它在没来MDN表达参考页


浏览器控制台打印是实现定义的

从JS移到浏览器后,您发布的图像显示了Chrome如何记录具有属性的数组,但这是根据console.log- > console.logger- > console.printer中的以下规范实现的:

打印机操作是实现定义的。它接受指示严重性的日志级别,要打印的参数列表以及实现特定格式选项的可选对象。args中出现的元素将是以下之一:

...

实现如何打印args取决于实现,但是实现应通过空格或类似内容将对象分隔开,因为这已成为开发人员的期望。

此外,2.3.3。常见的对象格式指出:

通常,对象将以适合其上下文的格式进行打印。本节介绍了格式化对象以使其在上下文中最有用的常见方法。应当注意的是,本节中描述的格式应用于最终将传递到打印机中的实现特定对象的表示形式,在那里将看到格式化的实际副作用。

具有通用JavaScript对象格式的对象是通用JavaScript对象的潜在可扩展表示形式。具有最佳使用格式的对象是特定于实现的,可能交互的表示形式的对象,被认为是最大有用和有用的。

经验证据支持上述陈述:

Firefox 67.0

ff

边缘42.17134.1.0

边缘

两种浏览器都不会在括号之间显示数组的属性,只会显示其数字索引元素(如果存在)。Chrome在其控制台规范的实现中呈现这些属性的事实并不意味着或暗示JS应该在其数组初始化程序中允许这种语法。浏览器的控制台表示与语言的语法之间根本没有任何关系。


chr*_*con 5

您在这里拥有的是一个被滥用为对象文字的数组。例如,数组也有一个length属性。就像这样,您可以为数组分配键,尽管您不应该这样做。

并不完全清楚你想在这里做什么,通常使用 Object.assign() 与对象文字而不是数组。它们有自己的功能。

Object.assign({}, n);
Run Code Online (Sandbox Code Playgroud)

将是一个理智的用例。


adi*_*iga 5

Object.assign()只是从第二个参数开始遍历所有对象的可枚举键并将它们添加到target对象中。

所以,Object.assign(arr, obj) 大致归结为(polyfill):

for(key in obj)
  arr[key] = obj[key]
Run Code Online (Sandbox Code Playgroud)

当您想更新数组的特定索引而不改变原始数组时,可以使用此技术(例如在反应中)

所以,这段代码

for(key in obj)
  arr[key] = obj[key]
Run Code Online (Sandbox Code Playgroud)

可以这样写:

const arr = [1, 2, 3, 4]
const clone = [...arr]
clone[2] = 10;
console.log(arr, clone)
Run Code Online (Sandbox Code Playgroud)