This is along the same lines as the question titled "Capturing Nashorn's Global Variables". I'm finding it very limiting not being able to intercept the assignment of variables to the global object.
For instance, say I eval the script "a = 10". Perhaps I want to call a listener to notify something that 'a' was added to the scope. The only way I could do this is to investigate the global object after the script is eval'd.
Or say i want to intercept an object being assigned to the global scope and substitute it for another; if it was using Bindings I could implement put, and delegate off to some other bindings:
public Object put(String name, Object value) {
//put a toStringed version of the object in scope
return delegate.put(name, value+"");
}
This way, when the code 'a=10' is evalled, it would put "10" in scope instead of 10.
It's handy having a Bindings interface to implement, but frustrating that I can't provide something like this implementation for the global object. ScriptObjectMirror is final, so I can't even overload this and hijack the subsequent call to the internal ScriptObject. Am I missing something?
So basically what you want to do is to intercept/trap assignments to arbitrary properties on some object. In your case, the global object.
Afaik, this was never really possible without some pretty hacky code indeed. A search for 'observables javascript' might help you with that, but be warned that you'll get into some muddy territory.
If this is meant for testing (as opposed to production code), a setTimeout / setInterval with some listener that periodically enumerates all properties of the global object and logs a warning if one was added might be good enough for you.
In the future, we'll have the Javascript Proxy standard to help us with this but I seriously doubt it is there yet in Nashorn. It's been a while since I worked with Nashorn but after the initial burst on the scene it has been quiet on the Nashorn front afaict...
Why is there a distinction between privileged and public methods?
Why should I even bother with public methods, aren't privileged
methods more natural? They feel more intuitive as they allow access
to private methods and variables like in java.
Is there a specific reason behind this or was this an error in the
spec(got a little ahead of myself there!) or am I missing something?
In what situation would you use a public method over a privileged method?
here is the code to demonstrate:
var Foo = function(){
var privateVar = "i am private";
function privateFunc(){
console.log(privateVar);
}
this.privilegedFunc = function(){
privateFunc(); // can access
}
};
Foo.prototype.publicFunc = function(){
privateFunc(); // cannot access
};
var foo = new Foo();
foo.privilegedFunc(); // prints "i am private"
foo.publicFunc(); // Uncaught ReferenceError: privateFunc is not defined
it's just like any OOP language (without the visibility keywords though), if you need a method to be called outside the instance, public, else, private.
Functions that are not bound to this, cannot be accessed outside the scope because they are defined and declared in the scope of the constructor function.
And as per your latest comment, there are many reasons and scenarios where you will have to expose an objects function in order to be used by other objects e.g.
As per your comment in this answer, lets see some advantages of the prototype approach.
By using prototype, you are able to change a method and the change will reflect to all instances that share the same prototype, without the prototype, each instance will have it's own version of the given method, therefore you will have to change them one by one.
Another advantage, is performance, functions/methods declared in the prototype are only created once, whereas without the prototype, each time you use the new keyword to instantiate from a constructor function, all functions inside the constructor functions scope will have to be created.
It's important to note that there's no distinction in the spec between "privileged" and "public" methods (in fact I don't think the spec uses these terms at all - Douglas Crockford does), they are governed by the exact same rules, the most fundamental of which in play being function scope.
Note: I'll follow your terminology in my answer, but I actually recommend against it: more often you'll find people calling your privileged methods public, and your public methods prototype methods.
In your example, this.privilegedFunc has access to the private variable privateFunc because they are defined in the same scope - that is, the scope of the Foo constructor function. privilegedFunc will be able to use its reference to privateFunc even when called from "outside", via the so-called closure mechanism of the language.
To answer your questions directly:
Why is there a distinction between privileged and public methods?
There isn't a fundamental distinction. You defined two functions in different scopes, and as such, they can reference different variables.
Why should I even bother with public methods, aren't privileged methods more natural?
Natural is quite a subjective term. However, if you don't wish to expose fields directly, you need to use a privileged function to manipulate them from the outside.
They feel more intuitive as they allow access to private methods and variables like in java.
That intuition is based only on familiarity :) No wonder that when you try to use Javascript as Java, the parts which work differently in the two languages will seem the least intuitive. This doesn't mean that you should try to imitate the style you would use in either in the other, some solutions are better suited for Javascript, some better for Java.
Is there a specific reason behind this or was this an error in the spec or am I missing something?
(Such a fundamental error in the spec?! God no.) I'm not sure what you mean by "this", but the difference in visibility is explained by function scopes, see above.
In what situation would you use a public method over a privileged method?
For example, if you don't need to expose private fields via closures. An other noteworthy difference is that functions on the prototype will be shared (i.e. effectively the same function instance) amongst instances, while private and privileged methods will be unique to the instance, which can have an effect on memory footprint.
What you call "privileged" methods aren't part of the language syntax. Rather, it's a design pattern. It is possible due to the fact that javascript implement closures (the ability of functions to access the scope of an outer function even after that outer function has returned).
There is a theory that all languages that implement closures (or even just first-class functions) can implement an object system. Several functional languages took this approach when adding OO to the language: that OO features are not part of the language syntax but a library that you can use (or even write yourself). One of the prime examples of this is CLOS (Common Lisp Object System) in Lisp. It's a library that adds OO features to the language without needing to modify the language syntax.
As you have discovered, using a closure to access local variables does a good enough job to emulate the "feel" of private variables and public methods. This is a feature of closures - that you can create your own OO system without needing OO features.
The OO system in javascript was added because OO was a big deal then. Admittedly, if Brendan Eich didn't add OO to javascript we could have evolved a (or several) OO systems from scratch using pure javascript. Indeed, in the early 2000s people weren't comfortable with the prototypal object system in javascript and developed their own OO system to emulate what they were used to.
In javascript, the OO system has no concept of private methods or variables. This was deliberate. Several other languages share this philosophy that private members are a "mistake". The idea that privacy is bad practice was borne out of years of experience using libraries that made a feature you needed to access private. For languages that encourages open source or distribution of code that's not too big of an issue. You can always modify the library code to export what you want. But for languages that encourages distribution of libraries as compiled binaries that's a big issue. At the time javascript was created, most OO languages had features allowing you to distribute your libraries as compiled binaries. So there was a small backlash against the concept of privacy.
So.. when would you use a closure to emulate private variables? Use it when you really need something like a private variable.
Why is there a distinction between privileged and public methods?
I'm assuming you read Douglas Crockford website (this page). It's a distinction I haven't really seen used by other authors. I don't make that distinction, but I do know that the function has access to the constructor closure.
Why should I even bother with public methods, aren't privileged methods more natural? They feel more intuitive as they allow access to private methods and variables like in java.
They have a different meaning than public methods.
A) They are defined by the constructor and as such, they have access to the constructor scope. That's their privilege.
B) They aren't shared by its prototype.
A means that the function will be instantiated every time the constructor is being called. When you use the prototype, it's just linked.
B means that they are essentially different functions.
obj1.privileged !== obj2.privileged
Is there a specific reason behind this or was this an error in the spec or am I missing something?
No error from where I see it. It's just a language feature.
In what situation would you use a public method over a privileged method?
When you don't need access to any closures inside the constructor and want to take leverage of the prototype chain.
Not sure about the semantics and naming convention, but as far as patterns, here's how I'd break this down for the most cases:
privateFunc:
I'd use this type of function whenever I want to encapsulate some functionality inside a function (either when reusing this function several times, or simply because it has a logical reason to do so) that I don't want to expose as an API, usually because it doesn't make sense as an API.
publicFunc:
I'd use this type of function whenever I want to expose an API, and the implementation doesn't require any "closed" (as in closure) variables. Basically anything that uses the state of an instance of the type but needs no other resources. Also for "static" methods that are used directly from the type (same as Object.keys() for example), but this won't be declared on the prototype but rather directly on the type.
priviledgedFunc:
Same use case as publicFunc except the use of helper, "closed" variables is either required or greatly simplify implementation. There's a downside to this technique in that these methods are properties of each instance, and incur runtime penalty to construct and assign.
Why is there a distinction between privileged and public methods?
It's a consequence, not a driver, of the language's design. You will actually do fine without bothering yourself with this terminology distinction I think.
Why should I even bother with public methods, aren't privileged
methods more natural? They feel more intuitive as they allow access to
private methods and variables like in java.
Is there a specific reason behind this or was this an error in the spec > or am I missing something?
In what situation would you use a public method over a privileged method?
There are a couple of situations where you would want to bother yourself with public methods that come to mind:
Privileged methods are defined everytime an object is created while public methods are defined once at parse time. So if you are writing something that creates a bucket load of object, e.g. particle system, you may want to use public method.
You can use public methods are pure function without instantiating an object.
Your are thinking about this the wrong way. You should be thinking about scope here and not access level (public/private/protected) Javascript is not a traditional object oriented programming language.
In your example, the "privateMethod" is simply scoped to the "Foo" function, and thus cannot be accessed outside the function. Your "privilegedFunction" is attached to "this" which in javascript is the context of the "Foo" function. You can access it from an "instance" of Foo as your example shows because of scoping, and it has nothing to do with access level.
I tried changing the constructor function of a class by
className.proptotype.constructor = newConstrcutor;
This property now refers to the newConstructor but when i try to create an instance of the class, still the old constructor is executed. So, what exactly is the use of className.proptotype.constructor ?
Thanks
Each constructor has a pointer to an object called prototype. The prototype is the main mechanism that JavaScript supports to share properties and methods among objects of the same type.
In addition, the prototype can be used to support inheritance; not exactly in the way that it is done in other OO languages like Java, c# etc. So you can imagine that there is a mechanism that allows the interpreter to navigate from one prototype to another via a chain that is implicitly formed.
In the same way that constructor point to a prototype object, the prototype can also point to its constructor; You can think of it as a relation between constructors and prototypes.
One of the uses of the className.proptotype.constructor property is when you want to debug your code. A JavaScript debugger would clearly state the type (the constructor it was created from) of an instance.
for more details you can read this
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor
I tried Dart SDK after the 1.0 release, and wrote a simple hello-world program in Dart.
Then, with the SDK tool, I generated the JavaScript file: helloworld.dart.js
I went through the output js code, I saw there is a function named convertToFastObject.
The definition is:
function convertToFastObject(properties) {
function MyClass() {};
MyClass.prototype = properties;
new MyClass();
return properties;
}
The usage code is like:
A = convertToFastObject(A);
B = convertToFastObject(B);
I know this code is for various kinds of Browsers, not for Chromium/Chrome only.
I cannot understand, why the function can make the Object faster?
This is a speed optimization for Google's V8 engine.
To be sure, this code snippet looks pretty weird: it assigns properties as the prototype of a constructor MyClass, then uses the constructor to build an instance with new MyClass(), and then returns properties. This is strange because 1) properties is never altered, and 2) the function never uses MyClass or the instance ever again.
Whenever you see strange behaviors like this, you can be fairly sure it's a speed optimization. In this case, the speed is gained by using V8's "hidden class" optimization. From a closely-related section of the Dart source:
// Use the newly created object as prototype. In Chrome,
// this creates a hidden class for the object and makes
// sure it is fast to access.
In the V8 engine, a constructed object is given a "hidden" C++ class to represent its set of properties. By constructing an object whose prototype is the properties object, the property values of properties become part of the new instance's C++ hidden class, which improves property-access speed.
I believe all objects in V8 have hidden classes by default, so the need for this technique isn't immediately obvious. However, it is possible for an object to lose its hidden class (and enter "slow mode" or "dictionary mode") by demonstrating that it doesn't benefit from the optimization. When an object deletes one of its properties or adds too many properties that are unrelated to the properties of any other objects, V8 assumes that a shared hidden class isn't valuable, because the object has no other similar object to share its hidden class with. This convertToFastObject function can re-instate a "slow mode" object's right to a hidden class by using it as the prototype of a newly constructed instance.
Related hidden class question, arising from a different Dart optimization: What is this generated code supposed (intended) to do?
Where data is stored in a script contributes directly to the amount of time it takes to execute. In general, there are four places from which data can be accessed in a script:
-Literal value
-Variable
-Array item
-Object property
Reading data always incurs a performance cost, and that cost depends on which of these four locations the data is stored in. if you create a property using the "Object.Prototype.", the scope here is "Object.Prototype" which is smaller than the object's scope "Object." that hold in addition the local vars and stuff non enumerable. That is why creating proprieties using Prototype have a faster access ! Read these 2 articles to get better understanding:
1- http://oreilly.com/server-administration/excerpts/even-faster-websites/writing-efficient-javascript.html 2-http://www.packtpub.com/article/using-prototype-property-in-javascript
I was doing a little reading up on OOP in JavaScript and was learning a bit about using the prototype object. In this article (a very good read, btw), the author says the following regarding declaring methods as attributes of a JavaScript class versus declaring the method on the prototype of the class:
This is actually not the optimal way to do it. A better way is to define the method on Person.prototype. Why is this better? Anyone? Anyone? Beuller? In the first version, each time you create a person, a new sayHi function will be created for him, where as in the second version, only one sayHi function is ever created, and is shared amongst all persons that are created - because Person.prototype is their parent. Thus, declaring methods on the prototype is more memory efficient.
After reading this, I began to thing about a JavaScript framework that I occasionally use to ease OOP with the language, Classy. In the examples given in their documents, and in pretty much all Classy code that I've ever written, I always declared the methods of a class directly as an attribute of it (as in right between the curly brackets instead of outside). I realize that directly declaring a method of a Classy class is done via object notation (JSON) instead of a normal JavaScript class having methods added directly inside of the function of the class.
What I am wondering is if objects created with Classy already take advantage of the performance savings of a method declared against a class's prototype. If I declare class methods in the same way as Classy's documentation, are the methods declared per instance of the class or declared as one method for all instances of the class to share? If the former, then am I able to, or supposed to, declare methods in a Classy class's prototype?
Sorry if I sound confusing.