In JavaScript, before using a variable, we need to declare and initialize it (assign value). Unlike JavaScript, while creating a variable in CoffeeScript, there is no need to declare it using the var keyword. We simply create a variable just by assigning a value to a literal as shown below.
But it is a strictly typed programming language. CoffeeScript has high object-oriented capabilities. But it is a dynamic type of programming language.
If you are looking to implement coffee script in html, take a look at this. You simple need to add a <script type="text/coffeescript" src="app. coffee"></script> to execute coffee script code in an HTML file.
jQuery.each
passes the current element as second parameter of the callback, so you don't have to reserve this
for jQuery:
processRows: ->
$("#my-table>tr").each (index, element) =>
id = $(element).attr("id")
@processRow id
Notice the use of the fat arrow (=>
) syntax for the callback function; it binds the function's context to the current value of this
. (this
in the callback function is always the same this
as the one at the time you defined the function.)
You say
Using something like
_this = this
outside the.each
function and passing it around isn't a great solution, either, since I reference many class variables inside processRow.
This is the most efficient solution, though. JavaScript's this
is a strange beast; you can keep it fixed inside of a nested function using the =>
operator, as arnaud576875 sugests in his answer (which is elegant but inefficient), or you can copy this
to another variable (which is efficient but inelegant). The choice is yours.
Note that some modern browsers support a bind
method on every function, which is more efficient than CoffeeScript's =>
. There's an open ticket to have =>
use the native bind
when available: https://github.com/jashkenas/coffee-script/pull/1408
Addendum: Of course, a more efficient alternative than any of the above would be to write
for element, index in $('#my-table>tr')
...
which would also solve your this
problem.
Your code...
class foo
@bar = 'bob loblaw'
processRows: ->
$("#my-table>tr").each ->
id = $(this).attr("id")
@processRow id
processRow: (id) ->
console.log @bar + id
Is transpiled to...
var foo;
foo = (function() {
function foo() {}
foo.bar = 'bob loblaw';
foo.prototype.processRows = function() {
return $("#my-table>tr").each(function() {
var id;
id = $(this).attr("id");
return this.processRow(id);
});
};
foo.prototype.processRow = function(id) {
return console.log(this.bar + id);
};
return foo;
})();
Which has assumed much about about the current context that it is translating to. Unfortunately, since jQuery manages context, you'll have to be explicit or declare a reference to your class's this
.
Incidentally, there are other issues with that generated code, take a look at this reduced case:
class foo
@bar = 'bob loblaw'
getBar: () ->
@bar
Transpiles to:
var foo;
foo = (function() {
function foo() {}
foo.bar = 'bob loblaw';
foo.prototype.getBar = function() {
return this.bar;
};
return foo;
})();
The results of attempting to use this piece of code:
> foo.bar;
"bob loblaw"
> var f = new foo();
undefined
> f.getBar();
undefined
Your code seems to expect that @bar
is an own property, but it's being created as a static property of the foo
function
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With