How to Implement Closures Using SpiderMonkey API? - javascript

I've been working with the SpiderMonkey C API and would like to implement a closure in C using their API. The one I would like to implement is fairly complex, but I can't even figure out how to do a simple one such as:
function x() {
var i = 0;
return function() { i++; print(i); };
}
var y = x();
y(); //1
y(); //2
y(); //3
I was wondering if anyone knows how I might do this. I found the JS_NewFunction method, but I don't actually know if that is a step in the right direction. Any help will be appreciated, thanks!

I don't know if there's a pure C way of doing closures or not. I would reccomend though, if you can, to just implement the functionality you need in javascript, and simply evaluate the javascript text in JSAPI. From there, use JSAPI to grab whatever handles/variables you need to implement your host functionality. It's really onerous to do javascripty things using JSAPI, avoid it if you can.

Narrated as if you're probably still interested, a year later.
Knitting my brows furiously at the documentation for JS_GetParent, I see
For some functions, it is used to implement lexical scoping (but this is an implementation detail).
and then, along with a list of API functions that create functions,
Some of these functions allow the application to specify a parent object. If the JSAPI function creating the object has a parent parameter, and the application passes a non-null value to it, then that object becomes the new object's parent. Otherwise, if the context is running any scripts or functions, a default parent object is selected based on those.
I might experiment with this later, but it seems that you might be able to do this either by (merely) creating the function in the API during the execution of the function that you want it to have the scope of.
Otherwise, you might be able to set the lexical scope of a function to some object manually using JS_SetParent, but the documentation keeps ominously calling that use of parents 'internal'.
</necro>

Related

Unexpected behaviours while invoking methods in Javascript ES6 classes

Primarily I'm a C# developer learning Javascript of late. I was trying out ES6 classes. I expected ES6 classes to behave like regular classes, but finding many anomalies.
class Test{
constructor(){
console.log("Constructor Invoked");
}
instanceMethod1(){
console.log("instanceMethod1 Invoked");
}
instanceMethod2InvokesInstanceMethod1(){
console.log("instanceMethod2InvokesInstanceMethod1 Invoked");
this.instanceMethod1();
//instanceMethod1(); //wont work in JS, but will work in C#
}
instanceMethod3InvokesStaticMethod1(){
console.log("instanceMethod3InvokesStaticMethod1 Invoked");
Test.staticMethod1();
//staticMethod1(); //Wont work in JS, but will work in C#
}
static staticMethod1(){
console.log("staticMethod1 Invoked");
}
static staticMethod2InvokingStaticMethod1(){
console.log("staticMethod2InvokingStaticMethod1 Invoked");
this.staticMethod1();
Test.staticMethod1();
//staticMethod1(); //Wont work in JS, but will work in C#
}
static staticMethod3InvokingInstanceMethod1(){
console.log("staticMethod3InvokingInstanceMethod1 Invoked");
new Test().instanceMethod1();
//this.instanceMethod1(); //wont work
}
}
var ob = new Test();
ob.instanceMethod1();
ob.instanceMethod2InvokesInstanceMethod1();
ob.instanceMethod3InvokesStaticMethod1();
Test.staticMethod1();
Test.staticMethod2InvokingStaticMethod1();
Test.staticMethod3InvokingInstanceMethod1();
My Questions:
Inside instanceMethod2InvokesInstanceMethod1 - Why calling instanceMethod1() wont work? Instance methods can't be invoked without an instance and hence calling an instance method within an instance method should make sense right?
Inside instanceMethod3InvokesStaticMethod1 - Test.staticMethod1() will work is fair enough. But why cant we directly call staticMethod1 ?
Inside staticMethod2InvokingStaticMethod1 - How this.staticMethod1() works ? What is the this object here ?
Inside a static method, this.staticMethod1() works, but not this.instanceMethod1(). Why ? I guess answer to question 3, should help answer this question.
Could someone please help me here.
Your first problem is assuming that Javascript behaves like C++. There are some similarities, but many differences. You should not immediately EXPECT that something that works in C++ will work in Javascript. They are not the same language and this is a common problem when C++ developers start learning Javascript (it happened to me too).
Inside instanceMethod2InvokesInstanceMethod1 - Why calling instanceMethod1() wont work? Instance methods can't be invoked without an instance and hence calling an instance method within an instance method should make sense right?
No, Javascript is not C++ and does not offer that feature. You must use an object prefix when calling a method, even inside a method of that object.
Inside instanceMethod3InvokesStaticMethod1 - Test.staticMethod1() will work is fair enough. But why cant we directly call staticMethod1 ?
Again, not a feature of Javascript.
Inside staticMethod2InvokingStaticMethod1 - How this.staticMethod1() works ? What is the this object here ?
You will need to learn the rules for how Javascript sets the value of this. It is generally set based on how the method is called (though there are some ways to supercede that (like with arrow functions). See Six ways this gets set for reference info.
In this specific question, because you called staticMethod2InvokingStaticMethod1 like this: Test.staticMethod2InvokingStaticMethod1();, the this pointer inside that function will be set to Test which means you can then call other static methods of Test by reference this.someOtherStaticMethod(). This is the most basic rule for how this is set. If you call obj.method(), then inside of method, the this pointer will be set to obj.
What is important to realize in Javascript is that a method is just an ordinary function that happens to be a property of some other object. It has no particularly binding to any instance. It only gets a binding to an instance when such a binding is specified in how the method is called. The one exception to this is arrow functions which are not used for methods. In those cases, a function can be declared with the arrow syntax and it's this value will be set to the lexical value of this at the point of declaration. If you're just starting to learn this, I'd suggest you skip arrow functions until you have everything else about this firmly in your grasp. They were not part of the language until a couple years ago so you can write perfectly fine Javascript without them (they are mostly a syntax shortcut for some purposes).
Inside a static method, this.staticMethod1() works, but not this.instanceMethod1(). Why ? I guess answer to question 3, should help answer this question.
Yes, as you expected, same answer as 3.

Add a method to a function that calls the function

Creating a module I ended designing a pattern where I attach methods to a function, and I'm not sure if it is correct. It is a closure that returns a function that has some methods attached which in turn calls the function itself.
I don't know if this is a bad practice or if it is considered to be ok. My objective is to provide ways to call the function with certain presents or in different ways, but I want to retain the ability to just call the function in its simpler form. Would this lead to memory leaks or anything like that?
I'm not making use of this at any point, so no danger of losing context.
Below you can find a code snippet with a simplified version.
function factory( general ){
var pusher = setTimeout(function(){ console.log('$',general) },1000);
var counter = 0;
function reporter ( specific ){
counter++;
console.log(counter, general , specific)
}
reporter.middleware = function ( something ){
clearTimeout(pusher);
return factory ( general + something )
}
return reporter
}
Thanks in advance.
Would this lead to memory leaks or anything like that?
No more than anything else. :-)
Since functions are proper objects in JavaScript, you can add properties to them, and those properties can refer to other functions. At a technical level, it's not a problem at all. For instance, jQuery does it with its $ function, which not only is callable ($()), but also has various other functions on it ($.ajax, $.Deferred, $.noConflict, etc.).
Whether it's good style or design is a matter, largely, of opinion, so a bit off-topic for SO. It may well be fine. Or it may be that you'd be better off returning a non-function object with your various functions on it as properties.

Coding Style in node.js

Style 1: Objects with constructor/prototype
function DB(url) {
this.url = url;
}
DB.prototype.info = function (callback) {
http.get(this.url + '/info', callback);
};
Style 2: Closures
function DB(url) {
return { info: async.apply(http.get, url + '/info') };
}
This is just an example and assume that there are more prototype methods and private methods involved.
I have read in posts One and Two that closure style is much more preferred in nodejs over the other. Please help me clarify why using this.something syntax is bad in nodejs.
You can give your opinion about which is better, but I mostly need to know about what are the advantages and disadvantages of each style when used in nodejs.
It's not about a style. These two functions do two completely different things.
Closure provides an access to local variables. This way you can create private variables that aren't accessible from the outside (like url in your example). But it has a performance impact since closure is created each time your object is created.
Prototype function is faster, but it is created before object, and don't know anything about an object itself.
Sometimes it even makes sense to use both of them at the same time. :)
PS: coding style is described here: https://npmjs.org/doc/coding-style.html . It doesn't explain your particular question, but I feel I have to balance those two links in previous answer with something more sensible. :)
Closures, when done correctly, allow you to encapsulate data through the use of the scope chain that cannot be modified by any other caller.
The prototype chain does not provide any protection in that same sense. The main drawback to the use of Objects in the fashion you describe, especially in a server or library scenario, is that the "this" keyword can be modified by the caller. You have no control over that and your code will break in wildly unpredictable ways if it occurs.
var mongo = new DB('localhost');
mongo.info.call(this); // broken
Now it may not happen as explicitly as that but if you are passing around objects or object properties as event handlers, callbacks, etc into other functions, you have no way of knowing - or protecting against - that type of usage. So the bottom line is that the 'this' keyword is not something you can bank on. While you can completely control your immediate scope with the use of closures.
In a similar vein, you also have no guarantee that your object's prototype chain has not been altered. Unless, of course, you are creating a closure over the object and returning a wrapper.
Lastly, the closure structure more closely follows the Law of Demeter since your object would, theoretically, be "reaching through" via the prototype chain. Using a closure to encapsulate other calls allows you to expose a single method which can result in calls to another service methods. This provides greater maintainability and flexibility since you now control the methods you expose directly without relying on the prototype chain. Of course, the LoD is just one way of doing things so that may or may not be important to you.
Node follow javascript standards. So any javascript coding style is a proper coding style for node.js. But the following links may give you the abbreviation of node.js coding style.
http://nodeguide.com/style.html
http://innofied.com/javascript-coding-standards-follow/
I use sjsClass: https://www.npmjs.org/package/sjsclass
Code example:
Class.extend('DB', {
'protected url': null,
__constructor: function (url) {
this.url = url;
},
info: function (callback) {
http.get(this.url + '/info', callback);
}
});
There are benefits to both styles and i think it depends on what your module/file is trying to expose. I heavily use closure style for most modules i use in my code. (like db abstraction, cache abstraction, mail etc..) and i use constructors/prototype for objects i create a lot of (like a node in a doubly-linked-list)
=== objects with attributes defined inside a closure
if you create an object (lets call it self),
inside its scope add a bunch of methods that access and attach to that object (self.x)
and at the end export self, everything has access only to what you added to self and cannot access the local variables inside the function where you created self
=== constructors and prototype
on the other hand if you create constructors and add methods/fields to them trough prototype every function that attaches itself to your instance has access to its internal variables and state.
==
there are some things that work easier with prototypes like EventEmitter
and Streams but it not very hard to attach them to objects also.
Javascript is both an object oriented language and functional language, and missing the heavy lifting tools on both sides
like proper inheritance ever seen this.super().super().someMethod() ?? I havn't
(you need it if both superclasses have the same method name)
or nomads or simple generators at the side of functional programming.
so for me it makes sense to use both, and pick the one that's most suited to your problem.
EDIT
There is one big benefit for objects which i totally forgot about.
In your second example you use a flow control library (async in this case but any defered library will do), it makes your code so much cleaner, however
for your example to work the get method of http.get has to be bound to http, which in many cases it is not. so then your code will look like http.get.bind(http)
if http were an object and get was defined in its scope it would always work and allows you to pass it around to other code. (like async)
IMHO this is discussion is larger than node ... it's about javascript language.
So I suggest read this:
http://addyosmani.com/resources/essentialjsdesignpatterns/book/
and google a lil about javascript design patterns!
constructor can be use like that
var db = new DB();
...
if(db instanceof DB){
...
}
Closures can make private variables like
function DB(url) {
var urlParam = '&a=b';
return {
info: async.apply(http.get, url + '/info' + urlParam)
};
}
urlParam is a private variables cannot be get or set
if you only want a static class or simple class, use Closures.

Using Function.prototype.bind or saved reference

This is subjective (opinion based) - but only to a degree, don't rush voting to close. Causing some arguments at work as everyone has a different opinion and people are trying to enforce a single way of doing it.
Simple context: when you have the option to save a reference in your closure to the instance or to use a polyfilled Function.prototype.bind, what possible disadvantages do you see to either approach?
To illustrate possible usecases, I just made up some class methods.
Pattern one, saved ref:
obj.prototype.addEvents = function(){
var self = this;
// reference can be local also - for unbinding.
this.onElementClick = function(){
self.emit('clicked');
self.element.off('click', self.onElementClick);
};
this.element.on('click', this.onElementClick);
};
Pattern two, a simple fn.bind:
obj.prototype.addEvents = function(){
// saved reference needs to be bound to this to be unbound
// once again, this can be a local var also.
this.onElementClick = function(){
this.emit('clicked');
this.element.off('click', this.onElementClick);
}.bind(this);
this.element.on('click', this.onElementClick);
};
Pattern two and a half, proto method to event:
obj.prototype.addEvents = function(){
// delegate event to a class method elsewhere
this.element.on('click', this.onElementClick.bind(this));
};
obj.prototype.onElementClick = function(){
this.emit('clicked');
this.element.off('click', this.onElementClick); // not matching due to memoized bound
};
Personally, I am of the opinion that there isn't a single correct way of doing this and should judge on a per-case basis. I quite like the saved reference pattern where possible. I am being told off.
Question recap:
Are there any GC issues to be considered / be mindful of?
Are there any other obvious downsides or pitfalls you can think of on either method?
Polyfill performance or event native .bind vs a saved ref?
My personal preference is to use the saved reference method. Reasoning about the value of this can be very hard sometimes because of how JavaScript treats this.
The bind is nice but if you miss the .bind(this) it looks like a bug.
The latter exposes too much; every time you need a callback you'd need to expose another helper in your API.
There are many ways to use prototyping. I think the most important thing is to pick one and stick to it.
Are there any GC issues to be considered / be mindful of?
Older engines don't infer what variables are still used from the closure and do persist the whole scope. Using bind does make it easy because the context is explicitly passed and the un-collected scope does not contain additional variables.
However, this doesn't make a difference if you're using a function expression anyway (as in patterns #1 and #2).
Are there any other obvious downsides or pitfalls you can think of on either method?
Saving reference:
needs an additional line for declaring the variable, sometimes even a whole new scope (IEFE)
Code can't be easily moved because you need to rename your variable
Using bind:
Easily overlooked on the end of a function expression (just like the invocation of an IEFE), it's not clear what this refers to when reading from top to bottom
Easily forgotten
I personally tend to use bind because of its conciseness, but only with functions (methods) declared elsewhere.
Polyfill performance or event native .bind vs a saved ref?
You don't care.
In your example, you actually don't need that reference to the bound function and the off method. jQuery can take care of that itself, you can use the one method for binding fire-once listeners. Then your code can be shortened to
obj.prototype.addEvents = function(){
this.element.one('click', this.emit.bind(this, 'clicked'));
};

How can I get to the parent scope of my inline javascript callback function?

I have something similar to this
function testfunction(runthis)
{
runthis();
}
function main()
{
var z = 15;
testfunction(function(){ alert(z); });
}
However it doesn't think z is in the same scope as my inline function. Without adding additional parameters to testfunction or my inline function, is there any way for my inline function to belong to the same scope as main? I'm trying to make callback functions work.
Edit: the above I imagine is a crappy example because it seems to be working. However the instance here http://pastebin.com/A1pq8dJR does not work unless I add .call(this,parameters) and manually set the scope (although I'm not exactly sure what this is doing). I would have thought this used there would refer to the scope imageLoaded has, but it is referring to the scope of imageBoxCreate? Could anyone explain why it wont work without that and why doing this fixed it?
If you just invoke a global function in javascript, the this object will be the top level window global object. If you invoke a function using the dot operator on an object, then this will be that object when the function runs. When you use function.call, you are explicitly specifying which object should be this. I think you are likely just making some scope mistakes with how you use this and var, but your code is long enough and involved enough that I'm not going to spend the time to debug it for you. If you can isolate you issue with a smaller code sample, folks should be able to help more easily.

Categories

Resources