繁体   English   中英

JavaScript闭包无法访问外部变量

[英]JavaScript closure can't access outer variables

, or . 我有这样的代码,不知道为什么在传递给nv.addGraph()的匿名函数中我无法访问外部函数中的变量,如

function (out) {
// Here you call the "this" means the widget instance. (@see Mylable.js)
var zcls = this.getZclass(),
uuid = this.uuid;

// The this.domAttrs_() means it will prepare some dom attributes,
// like the pseudo code below
/*
 * class="${zcls} ${this.getSclass()}" id="${uuid}"
 */
var a = this.domAttrs_();
out.push('<span ', this.domAttrs_(), '>fds</span><div id="chart"><svg></svg></div>');



nv.addGraph(function() {
    var chart = nv.models.multiBarChart()
    .transitionDuration(350)
    .reduceXTicks(true)   // If 'false', every single x-axis tick label
    // will be rendered.
    .rotateLabels(0)      // Angle to rotate x-axis labels.
    .showControls(true)   // Allow user to switch between 'Grouped' and
    // 'Stacked' mode.
    .groupSpacing(0.1)    // Distance between each group of bars.
    ;

    chart.xAxis.tickFormat(d3.format(',f'));

    chart.yAxis.tickFormat(d3.format(',.1f'));

    var data = [{
        key: 'Some key',
        color: '#ff44ee',
        values: [{
            x: 1,
            y: 3
        }, {
            x: 3,
            y: 4
        }]
    }]

    d3.select('#chart svg').datum(data).call(chart);
//      d3.select('#chart svg').datum(this.model.data).call(chart);

    var someData = this.model.data;

    nv.utils.windowResize(chart.update);
    return chart;
});

这个函数以某种方式在ZKoss Widget中使用,所以在这个函数中可以访问它的属性,比如this.model,但是在内部匿名函数中是不可能的。 我不知道它有什么问题,我刚开始用JS编写代码。

你不能在你的闭包中访问azcls ,但你应该没有问题。

对于this ,它始终是由函数的调用者设置的函数本地引用。 如果你想获得this由你需要或者将它复制到一个局部变量如父功能看,

var that = this;

在父然后参照that代替的this在封闭,或者,可替换地,可以调用bind()在经过在此,如功能。

nv.addGraph(function () {
   ...
}.bind(this));

这将导致this在功能相同的值作为父母的this

JavaScript中的this关键字与其他OO语言(例如Java)的工作方式不同。 它的值是在运行时确定的,它完全取决于我们调用函数的方式。

可以通过四种不同的方式调用函数:

  1. 构造函数调用:使用new关键字; 这是指新创建的实例

    function Car = function(){// ...} var car = new Car();

  2. 函数调用:调用在某个范围内定义的函数,例如全局范围。在这种情况下,它指的是全局对象

    function someFunc(){} someFunc();

  3. 方法调用:调用定义为对象成员的函数时。 例如

    var obj = {func:function(){}} obj.func();

在这种情况下,这指向对象本身。

4调用/应用:最后,可以在Function构造函数原型上定义的两个方法的帮助下调用函数。 在这种情况下,我们可以自己设定价值; var obj = {func:function(){}} function someFunc(){}

someFunc.call(obj);

在您的情况下,为了访问this.model您需要明确定义this关键字指向的位置。

你必须选择:

  1. 定义一个局部变量,例如var that = this;
  2. 使用ES5 bind方法

    nv.addGraph(function(){...} .bind(this));

内部匿名函数的范围与包含函数的范围相同。

您可以考虑传入zcls ,或者在传递给nv.addGraph的函数中定义它

MDN解释得非常好: https//developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope

您可以定义函数参数,然后按名称传递它。 例如:

var fcnArg = function() { ... }

nv.addGraph(fcnArg);

关于这个的另一个很好的讨论在这里: 在javascript函数中传递函数作为参数

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM