Why is coffescript creating this closure [duplicate] - javascript

This question already has answers here:
How do I define global variables in CoffeeScript?
(9 answers)
Closed 7 years ago.
I'm learning CoffeeScript I have this code:
class Person
constructor: (#firstName, #lastName) ->
sayHi: () ->
return "Hi, I'm #{#firstName} #{#lastName}"
And is generating this javascript code:
// Generated by CoffeeScript 1.10.0
(function() {
var Person;
Person = (function() {
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
Person.prototype.sayHi = function() {
return "Hi, I'm " + this.firstName + " " + this.lastName;
};
return Person;
})();
}).call(this);
I want to create instances of that class, but since it's inside the closure I can't how should I do that?

An option that is slightly less hackish is the # operator (which is the same as this). In a browser environment, this will point to window, in node.js, it will point to exports.
class #Person
constructor: (#firstName, #lastName) ->
sayHi: () ->
return "Hi, I'm #{#firstName} #{#lastName}"
window.Person only works on the browser, the # will work for node and the browser. See https://stackoverflow.com/a/24352630/227299
Alternatively, you can run coffescript with the -b (--bare) option and the wrapping function won't be created.

change a bit declaration of a class
class window.Person
constructor: (#firstName, #lastName) ->
sayHi: () ->
return "Hi, I'm #{#firstName} #{#lastName}"

Related

Javascript Objects Clarification [duplicate]

This question already has answers here:
Self-references in object literals / initializers
(30 answers)
Closed 4 years ago.
am a beginner learning javascript and was playing around with Objects and am wondering why this code is throwing an error.
var a = {
greeting: "Hello",
greet: this.greeting + "John"
}
console.log(a.greet);
While it's been clarified why your code throws an error, I wanted to explain how you could have it instead.
Javascript makes no difference between ordinary functions and constructors, to a class is just a call to new function with any function in front of it.
Therefore, a way the object can reference itself is by using a function body as its definition:
const AClass = function () {
this.greeting = 'Hello'
this.greet = this.greeting + ' John'
}
const a = new AClass()
console.log(a.greet)
Shorthand since you aren't going to create more than one AClass object (at least in your example):
const a = new function () {
this.greeting = 'Hello'
this.greet = this.greeting + ' John'
}()
console.log(a.greet)
Yours doesn't work because of the problems described in the comments.
I'm guessing that you want something like this:
var a = {
greeting: "Hello",
greet: function() {return this.greeting + " John"}
}
console.log(a.greet());
Or like this:
var a = (() => {
var greeting = "Hello"
return {
greeting,
greet: greeting + ' John'
}
})()
console.log(a.greet);
The first one makes greet a function, which means that it will respond to later changes in greeting. The second one creates an object based on the greeting value. But you have to use a local variable for the reference, since your this at the time of construction is not the new object but some outer scope, possibly something like window.
This question you have is explained here: How Do I reference objects proerty at creation
In order to do what you want you can use an object getter.
var b = {
greeting: "Hello",
get greet() { //this a getter that accesses greeting
return this.greeting + " John";
}
}
console.log(b.greet);

In JavaScript, what is the benefit of wrapping a pseudo class in an IIFE? [duplicate]

This question already has answers here:
What is the purpose of wrapping whole Javascript files in anonymous functions like “(function(){ … })()”?
(10 answers)
Closed 7 years ago.
Here is an example of a pseudo class in an IIFE
// cow.js
(function(exports) {
"use strict";
function Cow(name) {
this.name = name || "Anon cow";
}
exports.Cow = Cow;
Cow.prototype = {
greets: function(target) {
if (!target)
throw new Error("missing target");
return this.name + " greets " + target;
}
};
})(this);
What is the benefit of that over the following:
"use strict";
function Cow(name) {
this.name = name || "Anon cow";
}
exports.Cow = Cow;
Cow.prototype = {
greets: function(target) {
if (!target)
throw new Error("missing target");
return this.name + " greets " + target;
}
};
Don't both of these end up adding the Cow 'constructor' function to the global scope?
The cow.js file is being included via the HTML document in a script tag. That means that the value of this is window. Isn't that the same global scope that both examples will use to add the function to?
Could someone provide an example of using this in a module or different scope?
This is not a duplicate, as the IFFE in the following related question does not take a parameter - What is the purpose of wrapping whole Javascript files in anonymous functions like “(function(){ … })()”?
The code was copied from here: https://nicolas.perriault.net/code/2013/testing-frontend-javascript-code-using-mocha-chai-and-sinon/
The difference is the scope - in the 1st case everything is defined in an anonymous function scope, in 2nd case in global scope. The benefit of IIFE is module encapsulation, you can define a function/class with the same name in each module without affecting another one.

Why does TypeScript wrap class in anonymous function? [duplicate]

This question already has an answer here:
How to do class implementation?
(1 answer)
Closed 7 years ago.
Let's have, for example, a Dog class:
class Dog {
static food;
private static static_var = 123;
constructor(private name) {}
speak() {
console.log(this.name + ', I eat ' + Dog.food + ', ' + Dog.static_var);
}
}
Compiled to JS:
var Dog = (function () {
function Dog(name) {
this.name = name;
}
Dog.prototype.speak = function () {
console.log(this.name + ', I eat ' + Dog.food + ', ' + Dog.static_var);
};
Dog.static_var = 123;
return Dog;
})();
This works equally well and is less complicated:
function Dog(name) {
this.name = name;
}
Dog.prototype.speak = function () {
console.log(this.name + ', I eat ' + Dog.food + ', ' + Dog.static_var);
};
Dog.static_var = 123;
Is there any (other than "aesthetic") reason for using the anonymous function wrapper?
The main difference between the two has to do with hoisting.
TypeScript compiles the class into an assignment of a function expression to a variable. That means the resulting constructor only starts to exist at the point of assignment. In the code that occurs before, Dog will be bound to undefined.
On the other hand, your implementation uses a plain function that is subject to hoisting -- any code in that scope, including code that occurs before the function, can invoke the Dog constructor.
I guess TypeScript prefers to ensure that a class does not exist before it is actually defined, possibly to allow redefining the class at several points in the same scope.

What is the difference between `this` and `prototype`? javascript oop [duplicate]

This question already has answers here:
Use of 'prototype' vs. 'this' in JavaScript?
(15 answers)
Closed 8 years ago.
While going through javascript course on codecademy.com, I've become slightly confused.
So first we've been learning how to add method to a Class:
function Dog (breed) {
this.breed = breed;
this.sayHello = function () {
console.log("Hello this is a " + this.breed + " dog");
}
};
var someDog = new Dog("golden retriever");
someDog.sayHello();
Then we started the "prototype". And there was this example:
function Dog (breed) {
this.breed = breed;
};
Dog.prototype.sayHello = function () {
console.log("Hello this is a " + this.breed + " dog");
}
var someDog = new Dog("golden retriever");
someDog.sayHello();
Both examples are giving the same result.
Are these two examples are just two ways doing same thing? Or there is a practical difference between two of them?
The difference is that in the second case, all instances share the same sayHello function. That's more efficient, especially if you create a lot of instances.
The prototype method sayHello is shared by all instances of the class Dog as opposed to adding it with this in the constructor which creates a fresh copy for each instance, wasting space and time.
Here is how the new operator works in words:
https://gist.github.com/Havvy/5037770
Here is how the new operator works using a picture:

Why embed the JavaScript class in an anonymous function() call?

I was reading about the new JavaScript-like language from Microsoft called TypeScript. In the playground (example section), there is a simple class in TypeScript syntax converted to JavaScript code. Coming from a Java programming background, it was interesting for me to learn how OOP is done in JavaScript as compiled from TypeScript.
The TypeScript code:
class Greeter {
greeting: string;
constructor (message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
var greeter = new Greeter("world");
var button = document.createElement('button')
button.innerText = "Say Hello"
button.onclick = function() {
alert(greeter.greet())
}
document.body.appendChild(button)
And the equivalent JavaScript code:
var Greeter = (function () {
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.greeting;
};
return Greeter;
})();
var greeter = new Greeter("world");
var button = document.createElement('button');
button.innerText = "Say Hello";
button.onclick = function () {
alert(greeter.greet());
};
document.body.appendChild(button);
The Typescript part is very similar to Java so I understand that. Now my question is why in JavaScript the body of the Greeter class is embedded in a an anonymous function() call?
Why not write it like this?
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.greeting;
};
What is the advantage/disadvantage of each method?
The following is called an Immediately Invoked Function Expression:
(function(){ ... })();
It is used to keep the global scope clean. Though, in this case it isn't necessary since the return value is assigned to a variable Greeter. The only time this pattern is useful is when you want "private" static members.
E.g.:
var Greeter = (function () {
var foo = 'foo', bar = 'bar'; /* only accessible from function's defined
in the local scope ... */
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.greeting;
};
return Greeter;
})();
This is to allow for private members. In this example, all members are public so your two constructions are equivalent. However, if you want to provide for private members you need to hide them from the calling scope via a closure. Thus if you have a private member like so:
class Greeter {
private greeting: string;
constructor (message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
You would probably get something like this:
var Greeter = (function () {
var greeting="";
function Greeter(message) {
greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + greeting;
};
return Greeter;
})();
The greeting variable will be available to any function defined inside the anonymous function, but invisible everywhere else.
Besides the obvious scoping/closure reasoning. Using an anonymous function that invokes itself immediately pre-loads (interprets) the class definition. This allows any JIT optimizations to be front loaded within the execution. In short, for larger more complex applications it will improve performance.
The anonymous function / self executing closure is usually used to encapsulate scope so that only the returned value is accessible outside of it. (or anything you attach to other objects, like window)
The anonymous function is probably there to prevent name collition with other parts of the code. Think of it this way, inside your anonymous function, you could even declare a variable called "$" to be whatever you want, and at the same time, be using jQuery on other parts of your code without conflict.
The closure is the sole mean to call the constructors with parameters:
var w = new Greeter("hello")
There are other methods but all complicated and with limitations and drawbacks.

Categories

Resources