Как получить доступ к переменным из функции внутри, выполняемой внутри другой функции? - PullRequest
0 голосов
/ 12 декабря 2018

Я выполняю рефакторинг моей https://github.com/perdugames/cacau библиотеки тестов, которую я сделал, чтобы узнать немного больше о JavaScript и тестировании.Проблема в том, что мне не нравится, как FIXTURE в настоящее время работает над этим, поэтому я решил провести рефакторинг и хотел получить результат ниже, но я все еще не знаю, как сделать так, чтобы функции "addTest" имели доступ к "x ".

const runner = new Runner();

runner.addSuite(() => {
    console.log('Suite 1');

    runner.addFixture(() => {
        console.log('Suite');
        const x = 10;
    });


    runner.addTest(() => {
        console.log('Test 1');
        console.log(x);
    });

    runner.addTest(() => {
        console.log('Test 2');
        console.log(x);
    });

});

runner.run();

Примечание: Конечно, без использования глобалов и без добавления в область действия" бегун ".

Ответы [ 3 ]

0 голосов
/ 12 декабря 2018

Я не верю, что это физически возможно.Вам нужно будет передать переменную в функцию, чтобы получить к ней доступ, если вы не хотите использовать глобальную переменную или она доступна в области видимости класса или объекта.

Хотя эта переменная должна находиться в вашей куче, невозможно передать ее адрес в область действия новой функции, не передавая ей что-либо, ни указатель, ни само значение.

0 голосов
/ 12 декабря 2018

Я нашел два способа решения проблемы, первый был:

function test(){  
    console.log(this.x * 2);
}
function fixture() {
    this.x = 5;
}
test.call(new fixture()) // 10

Это худший способ, который я нашел, так как мне всегда придется использовать «это», и мне все равно придетсяиметь дело с FIXTURE как функцией конструктора, в противном случае было бы лучше использовать литерал объекта в этом случае.

Второй вариант, который я выбрал, более прост, и он уже соответствует тому, что я готов:

const runner = new Runner();

runner.addSuite(() => {
    console.log('Suite 1');
    var x;
    runner.addFixture(() => {
        console.log('Suite');
        x = 1;
        x++;
    });
    runner.addTest(() => {
        console.log('Test 1');
        console.log(x); // 2
    });

    runner.addTest(() => {
        console.log('Test 2');
        console.log(x); // 2
    });

});
0 голосов
/ 12 декабря 2018

На самом деле, вы должны использовать контексты.Пожалуйста, прочитайте больше о контекстах в JavaScript.Есть много сайтов.

В вашем случае вы можете назвать контекст

obj.funcA(() => {
    let ctx = this;
    console.log('A');

    obj.funcA1(() => {
        let ctxFncA1 = this // context of previous level... etc.
        console.log('A1');
        const x = 10;
    });

    // ... you get the point.    
});

В общем, то, что вы пытаетесь сделать, это не "хорошо".Если вы создадите объектный класс, язык JavaScript может позволить вам делать что угодно, но вы не должны этого делать.

Возможно, вам стоит заняться программированием объектов на JavaScript (книга или учебный веб-сайт).

На самом деле у вас есть пример, описывающий почти то, что вы хотите: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let (Кодскопировать / вставить оттуда.)

var Thing;

{
  let privateScope = new WeakMap();
  let counter = 0;

  Thing = function() {
    this.someProperty = 'foo';

    privateScope.set(this, {
      hidden: ++counter,
    });
  };

  Thing.prototype.showPublic = function() {
    return this.someProperty;
  };

  Thing.prototype.showPrivate = function() {
    return privateScope.get(this).hidden;
  };
}

console.log(typeof privateScope);
// "undefined"

var thing = new Thing();

console.log(thing);
// Thing {someProperty: "foo"}

thing.showPublic();
// "foo"

thing.showPrivate();
// 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...