Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/474.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_Reference_Ecmascript 6_Es6 Modules - Fatal编程技术网

Javascript引用与绑定…什么';有什么区别?

Javascript引用与绑定…什么';有什么区别?,javascript,reference,ecmascript-6,es6-modules,Javascript,Reference,Ecmascript 6,Es6 Modules,我最近在凯尔·辛普森(Kyle Simpson)的《你不知道JS:ES6》中读到了以下内容 “[ES6模块导出]到内部模块定义中标识符的实际绑定(几乎像指针)。” 我的困惑是这些绑定与引用有什么不同 我知道JS中的引用仅适用于非基本类型(如对象),因此 let object1 = {a: 1}; let object2 = object1; object1和object2现在指的是同一个对象(它们都是对同一对象的引用)。 如果我将属性添加到object2,我也将属性添加到object1 obj

我最近在凯尔·辛普森(Kyle Simpson)的《你不知道JS:ES6》中读到了以下内容

“[ES6模块导出]到内部模块定义中标识符的实际绑定(几乎像指针)。”

我的困惑是这些绑定与引用有什么不同

我知道JS中的引用仅适用于非基本类型(如对象),因此

let object1 = {a: 1};
let object2 = object1;
object1
object2
现在指的是同一个对象(它们都是对同一对象的引用)。
如果我将属性添加到
object2
,我也将属性添加到
object1

object2.b = 2;
console.log(object1.b); // 2
我可以看到,绑定可以应用于基本类型和非基本类型

// foo.js
export let count = 1;
export function incrementCount() { count++; }

// bar.js
import {count, incrementCount} from foo;
console.log(count); // 1
incrementCount();
console.log(count); // 2
除了原语值也可以共享绑定(而引用仅限于非原语类型)之外,绑定是否与引用类似


我觉得我在这里遗漏了什么…

效果不是特定于原始值的,它就像访问对象上的属性一样

例如:

let foo = {a: 1};
let bar = foo;
foo = {b: 2};

console.log(bar); // {a: 1}
但是:

所以bar的
a
与foo的
a
绑定在一起,并且具有完全相同的值,无论是原语还是引用。

a是“名称所指内容”的一个非常通用的术语。作用域中的每个标识符都绑定到某个对象。通常,它们解析为可变环境中的变量(中的存储插槽),但也有例外情况(例如,带有的或全局对象)

是指向某种结构的指针的术语。例如,对象被称为“”,因为它们引用具有标识的可变属性容器

ES6模块现在引入了一种新的绑定类型,这在以前是未知的。它不是一个普通的变量,而是对另一个变量的引用——从另一个模块导出的变量。如果模块变量更改,这将通过导入反映出来-它们都指向同一个环境记录槽。

导出
声明添加从本地名称到中名称的映射,而
导入
声明添加从相应模块接口中的名称到本地名称的映射。当一个模块被实例化时,它指向与导出模块中的本地绑定相同的环境。

尽管@Bergi给出了很好的回答,但我想为背景知识较少的用户提供更详细的回答

名称绑定 名称绑定是根据Javascript的词法范围规则将标识符与命名内存块(变量)关联起来。需要名称绑定,因为标识符可以存在于不同的作用域中,因此可用于不同的变量:

函数f(){let x=0} 设x=1; {设x=2} {设x=3; {设x=4; {console.log(x)}//日志4 }
}“除了原语值可以共享绑定而不能共享引用之外,绑定是否与引用类似?”——另外,它是只读的。仅供参考,您的示例
让a=1;导出默认值a
不导出
a
的实时版本,您希望
让a=1;导出{a作为默认值}以使其工作<代码>导出默认值a在此上下文中与导出默认值4+5没有区别,将计算表达式并为其创建您无权访问的绑定。
导出默认X的唯一情况
确实为声明创建了活动绑定,例如导出默认类a{}
@loganfsmyth:你确定吗?我的印象是
export default a
export{a as default}
是等价的;导出默认值a相当于
设a=1;让_secret=a;导出{u secret作为默认值}。谢谢@loganfsmyth。将编辑问题以反映这一点。实际上,绑定将标识符与存储位置(包含值)相关联,而不是与值本身相关联。否则,输入一个值就行不通了。当你说默认的导出是不共享的,这真的很让人困惑。尤其是在您的示例中,
o
是一个始终共享的对象(参考值)。@Bergi关于您的第二条评论:但不会是
export default o
*default*
的本地名称,因此无法从模块内访问创建的绑定?因此,
从“模块”导入o;o、 foo=“bar”
不会影响模块中的
o
。是的,这样一个默认导出的绑定是不可访问的,因此您不能重新分配其他内容,但所有内容都在模块之间共享(这就是整点:导入模块中的
o
引用与
*default*
相同的存储位置)-而且,正如答案的第二部分所解释的,对象始终是共享的,即使它们包含不同的变量(导出模块中的
o
*default*
)。
// foo.js
let a = {a: 1};
function mutateA() {
  a = {b: 2};
}
export a;
export mutateA;
// bar.js
import {a, mutateA} from foo;

console.log(a); // {a: 1}
mutateA();
console.log(a); // {b: 2}