[javascript] CoffeeScript에서 전역 변수를 어떻게 정의합니까?

Coffeescript.org에서 :

bawbag = (x, y) ->
    z = (x * y)

bawbag(5, 10) 

컴파일 :

var bawbag;
bawbag = function(x, y) {
  var z;
  return (z = (x * y));
};
bawbag(5, 10);

node.js에서 coffee-script를 통해 컴파일하면 다음과 같이 요약됩니다.

(function() {
  var bawbag;
  bawbag = function(x, y) {
    var z;
    return (z = (x * y));
  };
  bawbag(5, 10);
}).call(this);

문서는 말합니다 :

다른 스크립트에서 사용할 최상위 변수를 작성하려면 창 또는 CommonJS의 내보내기 오브젝트에서 특성으로 해당 변수를 첨부하십시오. CommonJS와 브라우저를 모두 대상으로하는 경우 실존 연산자 (아래에서 설명)는 추가 할 위치를 파악할 수있는 안정적인 방법을 제공합니다. root = exports? 이

CoffeeScript에서 전역 변수를 어떻게 정의합니까? ‘창에 속성으로 첨부하는 것’은 무엇을 의미합니까?



답변

coffee script에는 varstatement 가 없으므로 coffee-script의 모든 변수에 대해 자동으로이를 삽입하므로 컴파일 된 JavaScript 버전이 모든 것을 전역 네임 스페이스 로 유출하는 것을 방지합니다 .

따라서 의도적으로 커피 스크립트 측면에서 전역 네임 스페이스에 “누설”무언가를 만들 수있는 방법이 없으므로 전역 변수를 전역 객체의 속성으로 정의해야 합니다 .

창에서 속성으로 첨부

이것은 전역 객체window.foo = 'baz';이므로 브라우저 케이스를 처리하는 것과 같은 것을 수행해야 함을 의미 합니다 .window

Node.js

Node.js에는 window객체 가 없으며 대신 exportsNode.js 모듈을 감싸는 래퍼로 전달되는 객체가 있습니다 ( https://github.com/ry/node/blob/master/src/node.js# 참조). L321 ), 그래서 Node.js를에 당신이해야 할 것 인 것이다 exports.foo = 'baz';.

이제 문서에서 인용 한 내용이 무엇인지 살펴 보겠습니다.

… CommonJS와 브라우저를 모두 대상으로 : root = exports? 이

이것은 분명히 커피 스크립트이므로 실제로 컴파일하는 내용을 살펴 보겠습니다.

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

먼저 exportsJavaScript에 존재하지 않는 변수를 참조하려고하면 SyntaxError가 발생하기 때문에 정의되어 있는지 확인합니다 (와 함께 사용되는 경우 제외 typeof)

따라서 exports존재하는 경우 Node.js (또는 잘못 작성된 WebSite …)의 경우 루트는를 가리키고 exports그렇지 않으면를 가리 킵니다 this. 그래서 무엇 this입니까?

(function() {...}).call(this);

.call함수를 사용 하면 함수 this내부를 전달 된 첫 번째 매개 변수에 바인딩합니다 . 브라우저 this가 이제 window객체가되는 경우 Node.js의 경우 전역 컨텍스트global객체 로도 사용할 수 있습니다 .

그러나 requireNode.js에 함수 가 있으므로 Node.js의 global객체에 무언가를 할당 할 필요가 없으며 대신 객체에 할당 exports한 다음 require함수에 의해 반환됩니다 .

커피 스크립트

모든 설명을 마친 후에는 다음을 수행해야합니다.

root = exports ? this
root.foo = -> 'Hello World'

foo전역 네임 스페이스에서 함수 를 선언합니다 .
그게 다야 🙂


답변

나에게 @atomicules가 가장 간단한 답변을 가지고있는 것처럼 보이지만 조금 더 단순화 할 수 있다고 생각합니다. 전역 객체로 @컴파일 this.anything하고 this참조 할 수 있도록 전역에 원하는 것을 앞에 배치해야 합니다.

그래서…

@bawbag = (x, y) ->
    z = (x * y)

bawbag(5, 10)

컴파일 …

this.bawbag = function(x, y) {
  var z;
  return z = x * y;
};
bawbag(5, 10);

node.js가 제공하는 래퍼 내부와 외부에서 작동합니다.

(function() {
    this.bawbag = function(x, y) {
      var z;
      return z = x * y;
    };
    console.log(bawbag(5,13)) // works here
}).call(this);

console.log(bawbag(5,11)) // works here


답변

Ivo가 그것을 못 박았지만 스타일 포인트를 사용하려는 경우 권장하지는 않지만 사용할 수있는 더러운 트릭이 하나 있다고 언급합니다. 백틱으로 이스케이프 처리하여 CoffeeScript에 JavaScript 코드를 직접 포함시킬 수 있습니다.

그러나 이것이 일반적으로 나쁜 생각 인 이유는 다음과 같습니다. CoffeeScript 컴파일러는 이러한 변수를 인식하지 못하므로 일반적인 CoffeeScript 범위 지정 규칙을 따르지 않습니다. 그래서,

`foo = 'bar'`
foo = 'something else'

컴파일

foo = 'bar';
var foo = 'something else';

그리고 지금 당신은 foo서로 다른 범위에서 두 가지를 가지고 있습니다. Ivy가 설명했듯이 전역 객체를 참조하지 않고 CoffeeScript 코드 에서 전역 을 수정하는 방법은 없습니다 foo.

물론 이것은 fooCoffeeScript에서 할당을 한 경우에만 문제가됩니다. foo초기 값을받은 후 읽기 전용이 된 경우 (예 : 전역 상수) 내장 JavaScript 솔루션 접근 방식이 다소 수용 가능할 수 있습니다 (여전히 그래도 권장하지 않음).


답변

node.js에서 coffee-script를 통해 코드를 컴파일 할 때 -b 옵션을 전달할 수 있습니다. 컴파일 된 코드는 coffeescript.org와 동일합니다.


답변

Ivo Wetzel의 답변에 추가하려면

Google 그룹 게시물exports ? this 에서만 문서화 / 언급 된 것을 찾을 수 있는 짧은 구문이있는 것 같습니다 .

즉, 웹 페이지에서 함수를 전역 적으로 사용 가능하게하려면 @접두어로 함수를 다시 선언하십시오 .

<script type="text/coffeescript">
    @aglobalfunction = aglobalfunction = () ->
         alert "Hello!"
</script>

<a href="javascript:aglobalfunction()" >Click me!</a>


답변

나는 당신이 달성하려고하는 것을 다음과 같이 간단하게 수행 할 수 있다고 생각합니다.

커피 스크립트를 컴파일하는 동안 “-b”매개 변수를 사용하십시오.

-b/ --bare 최상위 함수 안전 래퍼없이 JavaScript를 컴파일하십시오.

그래서 이런 식으로 뭔가 : coffee -b --compile somefile.coffee whatever.js

이것은 CoffeeScript.org 사이트에서와 같이 코드를 출력합니다.


답변

당신이 나쁜 사람이라면 (나는 나쁜 사람입니다.), 당신은 다음과 같이 간단하게 얻을 수 있습니다 : (->@)()

에서처럼

(->@)().im_a_terrible_programmer = yes
console.log im_a_terrible_programmer

이것은 일반적으로 ‘함수 호출 패턴 (function-call invocation pattern)’이라고 Reference하는 Function‘베어'(즉, 또는 func()대신 )를 호출 할 때 항상 해당 실행 컨텍스트 의 전역 객체에 바인딩 되기 때문에 작동합니다 .new func()obj.func()this

위의 CoffeeScript는 단순히 다음과 같이 컴파일됩니다 (function(){ return this })(). 글로벌 객체에 안정적으로 액세스하기 위해 이러한 동작을 수행하고 있습니다.