闭包和解构——解构函数不能互相调用?
Closures & Destructuring — Destructured functions can't call each other?
我有如下内容:
let MM = {
a: function(){
b();
},
b: function(){
console.log('b');
}
};
function makeClosure(M) {
let { a, b } = M;
function a2(){ b2() };
function b2(){ console.log('b2'); };
return function( arg ){
if ( arg === 1 ) a();
if ( arg === 2 ) a2();
}
}
let c = makeClosure( MM );
////////////////////////////////////////////
// RESULTS
c( 1 ); // b() doesn't exist
c( 2 ); // b2() exists just fine
let MM = {
a: function(){
b();
},
b: function(){
console.log('b');
}
};
function makeClosure(M) {
let { a, b } = M;
function a2(){ b2() };
function b2(){ console.log('b2'); };
return function( arg ){
if ( arg === 1 ) a();
if ( arg === 2 ) a2();
}
}
let c = makeClosure( MM );
////////////////////////////////////////////
// RESULTS
c( 1 ); // b() doesn't exist
c( 2 ); // b2() exists just fine
为什么会出现以上Results的结果?我认为解构应该等同于声明。为什么解构后的b没有被a找到?它们存在于同一范围内?
有什么方法可以让它工作吗?出于组织原因,我更愿意解构。由于各种原因,我无法将它们保留为方法。
MM.a
的词法范围内没有名为 b
的独立函数,因此从 makeClosure
调用 a()
会导致错误,因为没有名为 b
的变量或函数b
可以在 MM
中的 a
函数中找到。
一种可能性是传递 a
函数来执行,这样 MM
不依赖于任何外部变量:
let MM = {
a: function(someFn){
someFn();
},
b: function(){
console.log('b');
}
};
function makeClosure(M) {
let { a, b } = M;
function a2(){ b2() };
function b2(){ console.log('b2'); };
return function( arg ){
if ( arg === 1 ) a(b);
if ( arg === 2 ) a2();
}
}
let c = makeClosure( MM );
c(1);
c(2);
另一种选择是 makeClosure
中的 call
a
具有具有 b
属性 的对象的调用上下文,就像 MM
,并让 MM.a
调用 this.b
:
let MM = {
a: function(){
this.b();
},
b: function(){
console.log('b');
}
};
function makeClosure(M) {
let { a, b } = M;
function a2(){ b2() };
function b2(){ console.log('b2'); };
return function( arg ){
if ( arg === 1 ) a.call({ b });
if ( arg === 2 ) a2();
}
}
let c = makeClosure( MM );
c(1);
c(2);
这个问题与解构没有任何关系 - 它只是普通的 JS 作用域规则。
我有如下内容:
let MM = {
a: function(){
b();
},
b: function(){
console.log('b');
}
};
function makeClosure(M) {
let { a, b } = M;
function a2(){ b2() };
function b2(){ console.log('b2'); };
return function( arg ){
if ( arg === 1 ) a();
if ( arg === 2 ) a2();
}
}
let c = makeClosure( MM );
////////////////////////////////////////////
// RESULTS
c( 1 ); // b() doesn't exist
c( 2 ); // b2() exists just fine
let MM = {
a: function(){
b();
},
b: function(){
console.log('b');
}
};
function makeClosure(M) {
let { a, b } = M;
function a2(){ b2() };
function b2(){ console.log('b2'); };
return function( arg ){
if ( arg === 1 ) a();
if ( arg === 2 ) a2();
}
}
let c = makeClosure( MM );
////////////////////////////////////////////
// RESULTS
c( 1 ); // b() doesn't exist
c( 2 ); // b2() exists just fine
为什么会出现以上Results的结果?我认为解构应该等同于声明。为什么解构后的b没有被a找到?它们存在于同一范围内?
有什么方法可以让它工作吗?出于组织原因,我更愿意解构。由于各种原因,我无法将它们保留为方法。
MM.a
的词法范围内没有名为 b
的独立函数,因此从 makeClosure
调用 a()
会导致错误,因为没有名为 b
的变量或函数b
可以在 MM
中的 a
函数中找到。
一种可能性是传递 a
函数来执行,这样 MM
不依赖于任何外部变量:
let MM = {
a: function(someFn){
someFn();
},
b: function(){
console.log('b');
}
};
function makeClosure(M) {
let { a, b } = M;
function a2(){ b2() };
function b2(){ console.log('b2'); };
return function( arg ){
if ( arg === 1 ) a(b);
if ( arg === 2 ) a2();
}
}
let c = makeClosure( MM );
c(1);
c(2);
另一种选择是 makeClosure
中的 call
a
具有具有 b
属性 的对象的调用上下文,就像 MM
,并让 MM.a
调用 this.b
:
let MM = {
a: function(){
this.b();
},
b: function(){
console.log('b');
}
};
function makeClosure(M) {
let { a, b } = M;
function a2(){ b2() };
function b2(){ console.log('b2'); };
return function( arg ){
if ( arg === 1 ) a.call({ b });
if ( arg === 2 ) a2();
}
}
let c = makeClosure( MM );
c(1);
c(2);
这个问题与解构没有任何关系 - 它只是普通的 JS 作用域规则。