[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에는 var
statement 가 없으므로 coffee-script의 모든 변수에 대해 자동으로이를 삽입하므로 컴파일 된 JavaScript 버전이 모든 것을 전역 네임 스페이스 로 유출하는 것을 방지합니다 .
따라서 의도적으로 커피 스크립트 측면에서 전역 네임 스페이스에 “누설”무언가를 만들 수있는 방법이 없으므로 전역 변수를 전역 객체의 속성으로 정의해야 합니다 .
창에서 속성으로 첨부
이것은 전역 객체 가 window.foo = 'baz';
이므로 브라우저 케이스를 처리하는 것과 같은 것을 수행해야 함을 의미 합니다 .window
Node.js
Node.js에는 window
객체 가 없으며 대신 exports
Node.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;
먼저 exports
JavaScript에 존재하지 않는 변수를 참조하려고하면 SyntaxError가 발생하기 때문에 정의되어 있는지 확인합니다 (와 함께 사용되는 경우 제외 typeof
)
따라서 exports
존재하는 경우 Node.js (또는 잘못 작성된 WebSite …)의 경우 루트는를 가리키고 exports
그렇지 않으면를 가리 킵니다 this
. 그래서 무엇 this
입니까?
(function() {...}).call(this);
.call
함수를 사용 하면 함수 this
내부를 전달 된 첫 번째 매개 변수에 바인딩합니다 . 브라우저 this
가 이제 window
객체가되는 경우 Node.js의 경우 전역 컨텍스트 가 global
객체 로도 사용할 수 있습니다 .
그러나 require
Node.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
.
물론 이것은 foo
CoffeeScript에서 할당을 한 경우에만 문제가됩니다. 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 })()
. 글로벌 객체에 안정적으로 액세스하기 위해 이러한 동작을 수행하고 있습니다.