使用对象解构赋值时,为啥将属性“名称”转换为字符串? [复制]
Posted
技术标签:
【中文标题】使用对象解构赋值时,为啥将属性“名称”转换为字符串? [复制]【英文标题】:When using object destructuring assignment, why is a property "name" cast to string? [duplicate]使用对象解构赋值时,为什么将属性“名称”转换为字符串? [复制] 【发布时间】:2017-11-08 07:34:20 【问题描述】:给定
let obj = name: 1;
console.log(typeof obj.name, obj.name); // `"number"`, `1`
在对象解构赋值中使用var
时,为什么name
标识符会转换为字符串?
let obj = name: 1;
var name = obj;
console.log(name, typeof name); // `1` `string`
但不使用let
或const
?
let obj = name: 1;
let name = obj;
console.log(name, typeof name);
我们可以通过定义不同的标识符来避免这种意外结果
let obj = name: 1;
var name:_name = obj;
console.log(_name, typeof _name);
虽然好奇 var
在浏览器环境中返回的结果与 let
或 const
的 name
标识符不同?
【问题讨论】:
这种行为跨引擎是否一致? @torazaburo 是的。 *nix 32 位的 chromium 58 和 firefox 53 产生相同的结果。没有在 mac 上的 safari 或 *indows 上的 edge 尝试过。 @torazaburo 推测与window.name
相关。虽然为什么 var
和 let
、const
的结果不同?
【参考方案1】:
此行为由执行代码的范围定义。
name
指的是window.name
属性,该描述符在赋值为window.name = 1
时有一个setter to convert it to string:
有效的浏览上下文名称是包含至少一个不以 U+005F LOW LINE 字符开头的字符的任何字符串。 (以下划线开头的名称是为特殊关键字保留的。)
当在全局范围内执行时,var name = ...
为window.name
赋值。而let
和const
声明块范围的变量。
当在本地范围内执行时,name
在这两种情况下都会引用本地变量:
(() =>
var obj = name: 1;
var name = obj;
console.log(typeof name); // 'number'
)();
【讨论】:
解决办法是使用块作用域和"use strict"
来避免意外结果?
@guest271314 是的。功能范围就足够了。这就是我们过去在任何地方都使用所有这些 IIFE 的原因——以免与全局范围发生冲突。为了清楚起见,我从 sn-p 中删除了“use strict”。默认情况下是可取的,但不会影响结果,因此这里不相关。
var
的这种行为是否是开发和实施let
和const
的原因之一?既然var
现在可以在浏览器环境中使用,还有一个避免使用var
的理由吗?
@guest271314 是的。如今,如果需要全球化,我们会做window.foo = ...
。使用var foo = ...
意外分配给全局是不可取的。实际上,使用var foo = ...
故意分配给全局也是不可取的,因为它在严格模式下不起作用。
我不会将全局 let
/const
声明称为“块作用域”。以上是关于使用对象解构赋值时,为啥将属性“名称”转换为字符串? [复制]的主要内容,如果未能解决你的问题,请参考以下文章