2014-02-14 7 views
0

У меня есть такой код и не знаю, почему в анонимной функции передается nv.addGraph() Я не могу получить доступ к переменным из внешней функции как , zcls или this.model.JavaScript закрытия не может получить доступ к внешним переменным

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.

+3

Я не вижу, где вы * попробуете * использовать 'a' или' zcls' в анонимной функции или где 'this.model' определяется в первую очередь. – Quentin

+0

Когда я писал, я не могу получить доступ к zcls. Я имел в виду, что я не вижу их в хром-отладчике. this.model определяется каркасом ZKoss, в отладчике я вижу его во внешней функции, но не во внутренней функции. – Alinoe

+0

Вы не можете видеть их в отладчике Chrome, потому что вы не обращались к ним, а не потому, что не можете. Если вы добавите к ним доступ в закрытии, они появятся в отладчике. Chrome оптимизирует закрытие (исключая переменные, которые не используются из закрытия), поэтому отладчик их не показывает. – chuckj

ответ

0

Внутренняя анонимная функция будет иметь ту же область действия, что и функция.

Вы можете рассмотреть вопрос о принятии в zcls, или определив его в функции вы передаете в nv.addGraph

MDN объясняет это очень хорошо: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope

Вы можете задать аргумент функции, а затем передать его имя. Например:

var fcnArg = function() { ... }

nv.addGraph(fcnArg);

Еще одна хорошая дискуссия по этому вопросу можно найти здесь: Passing a function as an argument in a javascript function

+0

Внутренняя функция не имеет той же области, что и содержащая функцию. Каждая функция выполняется в своей области; Это цепочка областей, которые позволяют внутренним функциям обращаться к переменным, которые определены во внешних областях. – ppoliani

+0

Правильно. Спасибо за разъяснения! – theUtherSide

1

Вы не имеют доступа к a или zcls в вашем закрытия, но вы не должны иметь никаких проблем делать так ,

Как и для this, это всегда локальная ссылка функции, заданная вызывающей функцией. Если вы хотите получить доступ к this, если смотреть в родительской функции вам нужно либо скопировать его в локальной переменной, такой как,

var that = this; 

в родителе, а затем обратитесь к that вместо this в замыкании, или, альтернативно , вы можете позвонить bind() о функции, проходящей в этом, например.

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

, который будет вызывать this в функции, чтобы иметь то же значение, как родителя this.

1

Это ключевое слово в JavaScript не работает так же, как в других языках OO, например Java. Это значение определяется во время выполнения и зависит исключительно от того, как мы вызываем функцию.

Есть четыре различных способа, что функция может быть вызвана:

  1. Конструктор вызова: Использование нового ключевого слова; Это относится к вновь созданному экземпляру

    функция Car = function() {// ...} var car = new Car();

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

    функция someFunc() {} someFunc();

  3. Вызов метода: при вызове функции, определенной как элемент объекта. например

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

В этом случае это указывает на сам объект.

4 Call/Apply: Наконец, функцию можно вызвать с помощью двух методов, которые определены в прототипе конструктора Function. В этом случае мы можем сами установить это значение; вар OBJ = {FUNC: функция() {}} функция SomeFunc() {}

someFunc.call(obj); 

В вашем случае, чтобы получить доступ к this.model вам необходимо явно определить, где вы хотите, чтобы это ключевое слово, чтобы указать.

Вы должны варианты:

  1. Определить локальную переменную, например, var that = this;
  2. Используйте bind метод ES5

    nv.addGraph (функция() { ... } .bind (это));

Смежные вопросы