我有如下内容:
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
为什么会出现上述结果结果?我认为解构应该等同于声明。为什么a找不到变形的b?它们存在于同一范围内吗?
有什么办法可以使这项工作吗?由于组织原因,我宁愿进行销毁。由于种种原因,我不能将它们保留为方法。
答案 0 :(得分:2)
在b
的词法范围内没有名为MM.a
的独立函数,因此从a()
调用makeClosure
会导致错误,因为没有名为{{可以在b
的{{1}}函数中找到1}}。
一种可能性是传递a
来执行函数,这样MM
不会依赖任何外部变量:
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);
call
中使用具有a
属性的对象的调用上下文,就像makeClosure
一样,并且有b
个电话MM
:
MM.a
此问题与解构无关-只是普通的JS作用域规则。