Minor drawback with Crockford Prototypical Inheritance - javascript

Just experimenting with different inheritance techniques in JS, and came across something mildly discomfiting about Crockford's Prototypal Inheritance pattern:
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
var C,
P = {
foo:'bar',
baz: function(){ alert("bang"); }
}
C = object(P);
It's all good - except when you log to console - the object appears as F. I've seen classical emulation in which you can repoint the constructor - is there a similar method to coerce the objects (console) reference?

The issue is that it's referring to the name of the constructor function. This quickly becomes a discussion about function expressions and statements and the name property. Turns out is is completely impossible to create a new named function at runtime without using eval. Names can only be specified using a function statement function fnName(){} and it's not possible to construct that chunk of code dynamically aside from evaling it. var fnExpression = function(){} results in an anonymous function assigned to a variable. The name property of functions is immutable so it's a done deal. Using Function("arg1", "arg2", "return 'fn body';") also only can produce an anonymous function despite being similar to eval.
It's basically just an oversight in the JS spec (Brendan Eich stated he regrets defining the display name the way he did 10 or so years ago) and a solution is being discussed for ES6. This would introduce more semantics for deriving a function's display name for debug tools or perhaps an explicit way to set and adjust it.
For now you have one route: eval, or some other form of late execution of configurable code. (eval by any other name...)
function displayName(name, o){
var F = eval("1&&function "+name+"(){}");
F.prototype = o;
return new F;
}
The function statement alone won't return from eval, but doing 1 && fnStatement coerces the thing into an expression which is returnable.
(Harmony Proxies also allow setting up functions that report names which you can configure without eval but that's not usable except in Node.js and Firefox currently).
I'll make a note here that all those "evil" functions that have been shat upon by Crockford and many others ALL have their place. eval, with, extending natives all enable specific techniques which are otherwise completely impossible and it's not wrong to use them when the occasion is right. It's just likely that most people aren't qualified to make the judgement of when that time is right. In my opinion using eval harmlessly to make up for poor language semantics and tools while waiting for a solution is perfectly acceptable and won't cause you any harm as long as you're not funneling arbitrary code into that eval statement.

If I log the object I can see: Object { foo="bar", baz=function()}, so I don't understand your problem...
Anyway, can use Object.create() instead of Crockford's function:
var P = {
foo:'bar',
baz: function(){ alert("bang"); }
}
var C = Object.create (P);
console.log (C):
Object { foo="bar", baz=function()}

Related

What is a proper, modern and cross-browser safe method of creating JavaScript classes?

I am confused with hundreds of ways of creating JS classes. One says that I should use prototypes, while others say that noone uses prototype beacuse it is "bad". On the other hand CoffeeScript uses prototypes but wraps a construction with a function whick returns itself (or something). I've seen function that returns an object, function that returns a function that returns an object etc..
I think it should be easy and no frameworks should be needed to create classes in a language - maybe I'm missing something.
There are also two (al least) ways of creating methods : foo: function() {} and function foo() {}. I've even seen those two ways in single class. The problem is that the first way results in creating annonymous functions (wich happens to be assigned to a field of an object) and debuggers say that error happened in annonymous function called by annonymous function etc.
I understand that JS is intended to be functional rather than OOP, but sometimes a class is the best way to describe a concept (e.g. a UI widget wants to be a class).
I'd be grateful for an example of proper constructed class with few words of explanation.
I think this article explains it well:
https://developer.mozilla.org/en-US/docs/JavaScript/Introduction_to_Object-Oriented_JavaScript
This is (I believe) the correct way to use classes in a prototype based language like javascript, and gives a good explanation of the concepts. I use this approach in my projects, and it seems to work in all modern browsers.
I think you can consider the code that CoffeeScript produces "good":
// Create a "class" named Foo = create a variable that contains whatever the
// self-invoking anonymous function returns (the function avoids the pollution
// the global namespace).
var Foo = (function() {
// Create the "class" = the constructor function that is supposed to be used
// with the "new" keyword to create instances (objects).
function Foo() {}
// Add a method "bar" (that's what the prototype is for!)
Foo.prototype.bar = function(baz) {
// Assign the value to a member variable of the current instance (this)
this.foobar = baz;
};
// ...add more stuff.
// Return only the function, every other local variable stays in this scope.
return Foo;
})();
If you are confident in using CoffeeScript, it has solid approach to classes, and gives you much clear syntax, compared to any other OOP framework at the same time.

Is it possible to create a function where [[prototype]] refers to another function

I would like to create function objects (yes, all functions are objects) with some control over the prototypal inheritance, that is, I would like one function to inherit from another.
I can make objects that have prototypal inheritance, and know to set the prototype property of a function performing as a constructor to initialize the [[prototype]] property of the object.
However, when creating a function, I must use the function operator or the Function constructor. I could try to swizzle Function.prototype, but (1) don't know if that is writable, and (2) that just seems quite dangerous [still, I should try doing that].
btw: I only care to do this for V8 within node.JS, so if there are means that work only for that environment, that would be acceptable.
For the record, I have seen this:
Is it possible to create a function with another prototype than Function.prototype?
In V8 (and most other browsers/engines except IE) you can change an object's prototype by setting the __prototype__ __proto__ attribute. Setting the prototype attribute will instead change the prototype that is used to create an object if the function is invoked as a constructor function. This should not be what you want.
Afaik there currently is no standard conform way to directly "subclass" a function (or array for that matter). There's only Object.create, but there is no Function.create or Array.create.
EDIT: I just realized that function objects do not have the __prototype__ attribute and changing / setting it will not turn an object into a function.
I believe though that I just recently watched a talk by Brendan Eich (the creator of JavaScript) in which he talked about Function and Array equivalents of Object.create. And infact, googling for "Function.create brendan eich" reveals the following blog post by Eich in which he talks about his wish to implement Function.create and Array.create.
EDIT 2: Ok, I screwed up. Pretty much. The non-standard attribute is of course __proto__ and not __prototype__. Setting __proto__ works fine for functions with some restrictions, which are:
To be able to call aFunction you must initialize it with an actual function, eg:
var aFunction = function () {};
This is important. Calling a function does not access the prototype chain, so if you define aFunction as an object and simply set the __proto__ attribute, you will not able to call aFunction.
You can now assign any other function to aFunction.__proto__ and reading any members (including methods) will correctly delegate to the prototype chain if the porperty is not found on aFunction itself.
Calling aFunction() will always invoke the function that was originally declared when aFunction was defined and will never invoke aFunction's prototype function. So the body of the function is not subject to inheritence.
Sorry for screwing up first with the name of the attribute. Hope this helps you nevertheless.
I came up with a solution that solves my needs. It is not cross-browser, but can be used cross-browser. My most important use case is as a module for node.JS. In that case, the mechanism of setting __proto__ works just fine, in which case I can call methods on the base function object
f.method(args...);
and it executed by code in the "super" function. Because the method is invoked by the method invocation pattern, "this" is set to the base function object, and so the proper properties are accessed even though the method resides in the "super."
Now for the in-Browser case: when I use my library client-side, I provide a proxy mechanism. Alas, code intended for the browser must be written differently. The invocation is:
f.proxy(methodName, args...);
The proxy method in the base function object is:
f.proxy = function (methodName) {
var p = this.constructor.prototype;
return p.proxy(this, methodName, arguments);
};
The proxy in the "super" object's prototype is:
proxy: function (instance, methodName) {
var args = Array.prototype.splice.apply(arguments, [2]),
method = this[methodName];
return (method) ? method.apply(instance, args) : undefined;
}
I probably should have named this "forward" or some such, but "proxy" is good enough.
Perhaps this mechanism might be useful to someone...
I think I understand what you're trying to do. In short, there's no way to really do it natively. You'd have to access the Function constructor, which for function expressions and definitions (i.e. anything using the 'function' keyword), isn't possible as far as I can tell. You could overwrite Function and just always use new Function([args], string) but I doubt you (or any JS programmer) want to do that.
Your best bet would probably be to send your function expressions to another function that returns the function object with your custom methods dynamically added:
wrapFunc = function(f){
f.customFunc = someCustomFunc;
return f;
}
var myNewFunc = wrapFunc(
function(){
//do something
}
);
myNewFunc.customFunc();

What do you call a set of Javascript closures that share a common context?

I've been trying to learn closures (in Javascript), which kind of hurts my brain after way too many years with C# and C++. I think I now have a basic understanding, but one thing bothers me: I've visited lots of websites in this Quest for Knowledge, and nowhere have I seen a word (or even a simple two-word phrase) that means "a set of Javascript closures that share a common execution context". For example:
function CreateThingy (name, initialValue)
{
var myName = name;
var myValue = initialValue;
var retObj = new Object;
retObj.getName = function() { return myName; }
retObj.getValue = function() { return myValue; }
retObj.setValue = function(newValue) { myValue = newValue; }
return retObj;
};
From what I've read, this seems to be one common way of implementing data hiding. The value returned by CreateThingy is, of course, an object, but what would you call the set of functions which are properties of that object? Each one is a closure, but I'd like a name I can used to describe (and think about) all of them together as one conceptual entity, and I'd rather use a commonly accepted name than make one up.
Thanks!
-- Ed
Crockford popularized the term "privileged method" to name the functions that have access to the scope of its constructor (where the private members are declared).
I would call them "A set of JavaScript functions that share a common enclosing scope".
The "execution context" part of the phrase you post, can create confusion between the Execution Contexts described in the specification, the this value, which also is popularly known as "the function context" or "object context", and the function scope, which is really what is being referenced here.
You could call it a class, but it's just a hash table with a bunch of entries, some of which are functions (or closures). The more idiomatic way to do this in Javascript is through the use of prototypes.
Some links to help you:
http://javascript.crockford.com/prototypal.html
http://www.crockford.com/javascript/private.html
Its close to the module pattern. Use an expression like so:
var thingy = (function(specObj) {
var my = {},
privateVar = blah,
someOtherPrivateVar = [];
my.getSomeVal() {
return specObj.someVal;
}
my.getAnotherVal() {
return specObj.AnotherVal;
}
}({
someVal: "value",
anotherVal: "foo"
}));
I initialized with an object literal because using a named object would allow the state of thingy to be changed by changing the named object. There are other options to do this.
Here's another good link on variations of the module pattern:
http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
Almost goes without saying, but Crockford's Javascript: The Good Parts contains a good treatment of this style and its specific benefits.

How override eval function in javascript?

For example:
(function() {
var proxied = window.eval;
window.eval = function() {
return proxied.apply(this, arguments);
};
})();
But this code is not working.
eval is magic. Unlike a ‘real’ function, it can read and write local variables in the caller:
function foo() {
var a= 1;
eval('a+= 1');
alert(a); // 2
}
Replace that eval with a proxied function and you've got a problem: the a+= 1 executes in the scope of the proxied function instead of foo. Depending on what's happening in the evaled code that could cause values to go missing, damage to the proxy's local, accidental globals, and so on.
It is, therefore, impossible to replace eval with a fully-working proxy. (For simple cases which don't need the locals, you can kind of get away with it.)
You can't. (There is a limited way of doing it, but it's quite limited and doesn't maintain the magic that bobince talks about.)
eval isn't a real JavaScript function in at least one major implementation (IE's JScript, at least not through IE7; haven't tested the new IE8 version), so right off the bat you're going to run into trouble, because you won't be able to call the original via apply (not that that really matters for eval).
The recent ECMAScript 5 specification specifically disallows overriding eval in strict mode (not that you're using strict mode there), which makes me suspect that there are very good reasons for not overriding it.
Although not portable, the following approach works in some places where it otherwise wouldn't (as it satisfies ES5's requirements that A) it be retrieved as a Reference in a MemberExpression, not a Value and B) it results in the ‘standard builtin function.’ — ES5 #15.1.2)
(function() {
var proxied = window.eval
with({get eval(){ console.log('eval called'); return proxied }}) {
/* client code */
}
})()
This obviously only applies if you can wrap the client code in a with() statement; though in many situations, that shouldn't be hard. Obviously, the same approach can shadow window with another object with all of its' properties, and a getter-proxied eval.
Environments that don't support SpiderMonkey's get statement, may be able to use ES5's defineProperty. Look into that yourself.
I tried this in FireFox 3.6.2 and it appears to work.
I typed this directly in the FireBug command line:
var proxied = eval;
eval = function() { alert("ha"); return proxied.apply(this, arguments);};
eval(7);
Maybe I didn't understand the question correctly, but I "override" eval()by creating a myEval() function that has the original eval() inside it and execute addition steps in myEval().
function myEval = function(value){
//do your stuff here
//for example
try {
value = eval(value)
} catch (error) {
console.log(error)
value = NaN
}
return value
}
Not only should you not do this, but I also think you probably can't. First, eval is a global function, and as such is not a member of window (as you tried above). Secondly as a global function it is highly likely that it is hard-wired into the VM and can't be overwritten.

Module pattern vs. instance of an anonymous constructor

So there's this so-called module pattern for creating singletons with private members:
var foo = (function () {
var _foo = 'private!';
return {
foo: function () { console.log(_foo); },
bar: 'public!'
}
})();
There's also this method that I found on my own, but haven't seen anything written about:
var foo = new function () {
var _foo = 'private!';
this.bar = 'public!';
this.foo = function () { console.log(_foo); };
}
I'm thinking there must be a reason why nobody writes about this while there's tons of articles about the module pattern. Is there any downside to this pattern? Speed, or browser compatibility perhaps?
In this case it seems you are using only one instance object of that "class". So may want to take look at what Douglas Crockford thinks about putting new directly in front of function:
By using new to invoke the function, the object holds onto a worthless prototype object. That wastes memory with no offsetting advantage. If we do not use the new, we don’t keep the wasted prototype object in the chain. So instead we will invoke the factory function the right way, using ().
So according to the renown javascript architect of Yahoo! you should use the first method, and you have his reasons there.
More-or-less, they give you the same result. It's just a matter of which path you want to take for it.
The 1st may be more popular since it's simply the mixture of 2 already common patterns:
(function closure() {
var foo = 'private';
/* ... */
}())
var singleton = {
bar : 'public'
};
However, prototype chaining would be the benefit of the 2nd pattern since it has its own constructor.
var singleton = new function Singleton() { };
assert(singleton.constructor !== Object);
singleton.constructor.prototype.foo = 'bar';
assert(singleton.foo === 'bar');
I don't see any substantial difference between the two. I would prefer the latter simply since it has much less punctuation clutter.
On the other hand the "module pattern" approach seems to be the most common and is becoming a well known pattern (due to the rise in JQuery). It might be better to stick with this recognised pattern not because it has any more technical merit than the other approach but just because it will likely be more recognizable (despite the heavy punctuation).
Douglas Crockford writes about the second one. As Greg says in his comments, I thought it was quite common, and I've used it in the past.
Edit: to actually answer your question - there's no downsides, the two are functionally equivalent (both create a closure containing the "private variables" and exposing other variables/methods publically), and have exactly the same browser support and performance characteristics. It just comes down to a matter of syntax - basically, where you put the () to actually invoke this function and get your closure, and whether you use the new keyword.

Categories

Resources