Замыкания и разрушения - Разрушенные функции не могут вызывать друг друга? - PullRequest
0 голосов
/ 27 августа 2018

У меня есть что-то вроде следующего:

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

Почему происходят вышеуказанные результаты?Я думал, что разрушение должно было быть эквивалентно декларации.Почему деструктурированный b не найден?Они существуют в одной области?

Есть ли способ заставить эту работу?Я бы предпочел провести деструкцию по организационным причинам.Я не могу хранить их как методы по разным причинам.

1 Ответ

0 голосов
/ 27 августа 2018

Не существует автономной функции с именем b из лексической области MM.a, поэтому вызов a() из makeClosure приводит к ошибке, поскольку внутри * не может быть найдена переменная или функция с именем b.1006 * функция в 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 звоните 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.

...