【问题标题】:How to access variables from a function inside executed inside another function?如何从另一个函数内部执行的函数访问变量?
【发布时间】:2018-12-12 11:39:38
【问题描述】:

我正在重构我的 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();

注意:当然没有使用全局变量,也没有添加到“runner”的范围内。

【问题讨论】:

  • 您可以在obj的范围内定义它,即obj.x
  • 你可以在funcA的范围内声明它,如果它在父级的范围内,它在技术上不被认为是全局的。
  • @Satpal 我更新了注释,在“对象”的范围内也不会。
  • 你的问题没有多大意义。在范围内声明的变量或常量不能在该范围之外访问。这就是范围的重点。您的代码是如此抽象,以至于无法说出您真正想要解决的问题。
  • @Rewire 也许,让我试试。但是“x”在“funcA”的范围内,函数“funcA2A”和“funcA2B”是否可以访问“x”?

标签: javascript function closures


【解决方案1】:

实际上,您应该使用上下文。请阅读更多关于 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

【讨论】:

  • 我想你给我指路了,我只是不知道学什么名字,我会学的。
  • 范围或上下文是您需要查找的关键字。这是一个很好的起点:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference
  • 我这样做是有原因的,我通过创建东西来学习 JavaScript,并且我正在重构我不久前做的一个测试库,这里是:github.com/perdugames/cacau。我不想谈论它,因为您会看到很多 cmets,例如“为什么不使用现有的?...”我已经厌倦了,我这样做是为了学习,因为我喜欢了解事情是如何运作的。
  • 我用真正的问题更新了问题。现在我会研究你给我的东西,谢谢。
【解决方案2】:

我不相信这在物理上是可能的。如果您不想要全局变量,或者让它在类或对象的范围内可访问,则必须将变量传递给函数才能访问它。

虽然这个变量应该在你的堆中,但是如果不向它传递一些东西,无论是指针还是值本身,就无法将它的地址传递给新函数的范围。

【讨论】:

  • 是的,但是我可以传递一个指针或它自己的值,我只是不知道正确的方法。
【解决方案3】:

我找到了两种解决问题的方法,第一种是:

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

这是我发现的最糟糕的方式,因为我总是不得不使用“this”,而且我仍然必须将 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
    });

});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多