Я только что узнал о модульном шаблоне. Я написал код, который стал достаточно сложным, и я хочу протестировать функцию. Проблема в том, что я не могу понять, как имитировать значение. Далее следует coffeescript, но я помещу сгенерированный javascript ниже, чтобы получить дополнительную помощь. Вот мой тест, который пытается имитировать поле с именем state, но всегда выводит "undefined":

root = exports ? this
root.test3 = (->
  root.test2.state = "abc"
  root.test2.doSomething()

  return {}
)()

И вот test2, который для целей этого вопроса можно рассматривать как производственный код:

root = exports ? this
root.test2 = (->
  state = undefined

  doSomething = -> alert state

  return {
    state: state
    doSomething: doSomething
  }
)()

Вот HTML, в котором я это использую, но я не думаю, что это имеет значение:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>TEST2</title>

    <script src="test2.js" type="text/javascript"></script>
    <script src="test3.js" type="text/javascript"></script>

    <style>
        canvas {
            border: 1px solid black;
        }
    </style>

</head>

<body>


<h1>This is a test</h1>

</body>
</html>

Test2 в Javascript:

var root;

root = typeof exports !== "undefined" && exports !== null ? exports : this;

root.test2 = (function() {
  var doSomething, state;
  state = void 0;
  doSomething = function() {
    return alert(state);
  };
  return {
    state: state,
    doSomething: doSomething
  };
})();

Test3 в Javascript:

var root;

root = typeof exports !== "undefined" && exports !== null ? exports : this;

root.test3 = (function() {
  root.test2.state = "abc";
  root.test2.doSomething();
  return {};
})();

Как я уже сказал, запуск этого оповещения undefined. Я хочу, чтобы он выводил «abc». Как я могу это сделать?

0
Daniel Kaplan 2 Июл 2013 в 06:13

1 ответ

Лучший ответ

Вы хотите использовать "это" в этом случае,

doSomething = function() {
    return alert(this.state);
};

В вашем коде «состояние» относится к переменной (через закрытие), которая не определена. Затем вы возвращаете объект, содержащий новое свойство «состояние». Вам не нужна первая переменная состояния, а только свойство в возвращаемом объекте.

'this' в doSomething относится к любому объекту, частью которого оно является. В test3 doSomething относится к возвращаемому объекту с параметром state, установленным в undefined. После установки состояния в test3 свойство объекта state больше не совпадает с частной переменной state в test2 - оно перезаписывается в test3.

По сути, вам не нужен шаблон модуля для желаемого эффекта, есть гораздо более простой способ:

root.test2 = {
    state: void 0,
    doSomething: function() {
        return alert(this.state);
    }
};

http://jsfiddle.net/rMJs5/

ОБНОВЛЕНИЕ :: Я забываю о части кофе:

root = exports ? this
root.test2 = (->
  doSomething = -> alert this.state
  return {
    state: undefined
    doSomething: doSomething
  }
)()

Или просто:

root = exports ? this
root.test2 = {
    state: undefined
    doSomething: -> alert this.state
}
1
Spencer Lockhart 2 Июл 2013 в 19:01
В определении функции для doSomething ...?
 – 
Spencer Lockhart
2 Июл 2013 в 18:59
Хорошо, это очень полезно, но что, если я хочу имитировать функцию вместо переменной? Представьте, что doSomething вызвал имя функции alertABC(). Как я могу изменить то, что alertABC() делает в test3?
 – 
Daniel Kaplan
2 Июл 2013 в 20:55