Di Coffeescript.org:
bawbag = (x, y) ->
z = (x * y)
bawbag(5, 10)
akan dikompilasi ke:
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
kompilasi melalui skrip kopi di bawah node.js membungkus itu jadi:
(function() {
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
}).call(this);
Documents katakan:
Jika Anda ingin membuat variabel tingkat atas untuk digunakan skrip lain, lampirkan sebagai properti di jendela, atau pada objek ekspor di CommonJS. Operator eksistensial (dibahas di bawah), memberi Anda cara yang andal untuk mencari tahu di mana menambahkannya, jika Anda menargetkan CommonJS dan browser: root = ekspor? ini
Bagaimana cara mendefinisikan Variabel Global lalu di CoffeeScript. Apa yang dimaksud dengan 'melampirkannya sebagai properti di jendela'?
javascript
coffeescript
Handloomweaver
sumber
sumber
window
objek atauexports
objek. tidak perlu membuat variabel global.window
(atauglobal
pada nodejs)Jawaban:
Karena skrip kopi tidak memiliki
var
pernyataan, skrip kopi secara otomatis memasukkannya ke semua variabel dalam skrip kopi, sehingga mencegah versi JavaScript yang dikompilasi dari membocorkan semuanya ke namespace global .Jadi karena tidak ada cara untuk membuat sesuatu "bocor" ke ruang nama global dari sisi naskah kopi hal-hal yang disengaja, Anda perlu mendefinisikan variabel global Anda sebagai properti dari objek global .
Ini berarti Anda perlu melakukan sesuatu seperti
window.foo = 'baz';
, yang menangani kasus browser, karena di sana objek global adalahwindow
.Node.js
Di Node.js tidak ada
window
objek, melainkan adaexports
objek yang dilewatkan ke pembungkus yang membungkus modul Node.js (Lihat: https://github.com/ry/node/blob/master/src/node.js# L321 ), jadi di Node.js apa yang perlu Anda lakukan adalahexports.foo = 'baz';
.Sekarang mari kita lihat apa yang tercantum dalam kutipan Anda dari dokumen:
Ini jelas skrip kopi, jadi mari kita lihat apa yang sebenarnya dikompilasi:
Pertama akan memeriksa apakah
exports
didefinisikan, karena mencoba referensi variabel yang tidak ada dalam JavaScript akan menghasilkan SyntaxError (kecuali ketika digunakan dengantypeof
)Jadi jika
exports
ada, yang merupakan kasus di Node.js (atau dalam WebSite yang ditulis dengan buruk ...) root akan menunjuk keexports
, sebaliknyathis
. Jadi apathis
?Menggunakan
.call
pada suatu fungsi akan mengikat bagianthis
dalam fungsi ke parameter pertama yang dilewati, dalam hal browserthis
sekarang akan menjadiwindow
objek, dalam kasus Node.js itu akan menjadi konteks global yang juga tersedia sebagaiglobal
objek.Tetapi karena Anda memiliki
require
fungsi di Node.js, Anda tidak perlu menetapkan sesuatu keglobal
objek di Node.js, sebagai gantinya Anda menetapkan keexports
objek yang kemudian dikembalikan olehrequire
fungsi.Kopi-Naskah
Setelah semua penjelasan itu, inilah yang perlu Anda lakukan:
Ini akan mendeklarasikan fungsi kita
foo
di namespace global (apa pun yang terjadi).Itu saja :)
sumber
global
,GLOBAL
danroot
benda-benda di node.js?ReferenceError
?(exports ? this).foo = -> 'Hello World'
global = exports ? this
. Klaim bahwa "dalam kasus Node.js itu akan menjadi konteks global ..." salah karenathis
variabel, ketika diperlukan atau dijalankan oleh node.js, dievaluasi sebagai cakupan modul. Jadi, jika Anda mengharapkan pengaturan alat peraga akan membuatnya dapat diakses secara global, Anda akan kecewa. Jika Anda ingin mengatur sesuatu secara global dalam konteks node.js, Anda perlu menggunakanglobal
variabel, bukanthis
.Bagi saya sepertinya @atomicules memiliki jawaban yang paling sederhana, tapi saya pikir ini bisa disederhanakan sedikit lagi. Anda harus meletakkan
@
sebelum apa pun yang Anda ingin menjadi global, sehingga ia mengkompilasithis.anything
danthis
mengacu pada objek global.begitu...
mengkompilasi ke ...
dan bekerja di dalam dan di luar pembungkus yang diberikan oleh node.js
sumber
this
tidak lagi mengacu pada objek globalwindow.myVariable
yang akan bekerja di mana saja.=>
alih-alih->
yang menginstruksikan naskah kopi untuk membuat fungsi di bawah namespace global iniIvo berhasil, tetapi saya akan menyebutkan bahwa ada satu trik kotor yang dapat Anda gunakan, meskipun saya tidak merekomendasikannya jika Anda mencari poin gaya: Anda dapat menyematkan kode JavaScript langsung di CoffeeScript Anda dengan menghindarinya dengan backticks.
Namun, inilah mengapa ini biasanya ide yang buruk: Kompiler CoffeeScript tidak mengetahui variabel-variabel tersebut, yang berarti mereka tidak akan mematuhi aturan pelingkupan CoffeeScript yang normal. Begitu,
kompilasi ke
dan sekarang Anda memiliki dua
foo
s dalam lingkup yang berbeda. Tidak ada cara untuk mengubah globalfoo
dari kode CoffeeScript tanpa merujuk objek global, seperti yang dijelaskan Ivy.Tentu saja, ini hanya masalah jika Anda membuat tugas
foo
di CoffeeScript — jikafoo
menjadi read-only setelah diberi nilai awal (yaitu konstanta global), maka pendekatan solusi JavaScript yang disematkan mungkin agak dapat diterima (meskipun masih tidak direkomendasikan).sumber
foo
variabel lokal , karenavar
mengangkat (JS memindai ke depan untuk semuavar
deklarasi dan menafsirkannya seolah-olah mereka berada di atas fungsi)expect = require('chai').expect;
membuatexpect
variabel tersedia di semua file pengujian saya!Anda bisa meneruskan opsi -b ketika Anda mengkompilasi kode melalui coffee-script di bawah node.js. Kode yang dikompilasi akan sama dengan di coffeescript.org.
sumber
-b
/--bare
langsung setelahcoffee
perintah.Untuk menambah jawaban Ivo Wetzel
Tampaknya ada sintaks steno untuk
exports ? this
itu saya hanya dapat menemukan didokumentasikan / disebutkan pada posting grup Google .Yaitu di halaman web untuk membuat fungsi tersedia secara global Anda mendeklarasikan fungsi lagi dengan
@
awalan:sumber
Saya pikir apa yang Anda coba capai dapat dengan mudah dilakukan seperti ini:
Saat Anda mengompilasi naskah kopi, gunakan parameter "-b".
-b
/--bare
Kompilasi JavaScript tanpa pembungkus fungsi keselamatan tingkat atas.Jadi sesuatu seperti ini:
coffee -b --compile somefile.coffee whatever.js
Ini akan menampilkan kode Anda seperti di situs CoffeeScript.org.
sumber
Jika Anda orang jahat (saya orang jahat.), Anda bisa sesederhana ini:
(->@)()
Seperti dalam,
Ini berfungsi, karena ketika memanggil a
Reference
keFunction
'bare' (yaitufunc()
,, bukannyanew func()
atauobj.func()
), sesuatu yang biasa disebut sebagai 'pola panggilan fungsi-panggilan', selalu mengikatthis
ke objek global untuk konteks eksekusi itu .CoffeeScript di atas hanya mengkompilasi ke
(function(){ return this })()
; jadi kami menjalankan perilaku itu untuk secara andal mengakses objek global.sumber
Karena naskah kopi jarang digunakan sendiri, Anda dapat menggunakan
global
variabel yang disediakan oleh node.js atau browserify (dan keturunan apa pun seperti coffeeify, skrip pembuatan gulp, dll).Di node.js
global
adalah namespace global.Di browserify
global
sama denganwindow
.Jadi hanya:
sumber