Minor flaw with Crockford's prototype inheritance

Just experimenting with different inheritance methods in JS and stumbled upon something soft discomfiting about Crockford 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); 

Everything is fine - except when you enter the console - the object is displayed as F. I saw a classic emulation in which you can move the constructor - is there a similar method for forcing references to objects (console)?

+8
javascript prototypal-inheritance
source share
2 answers

The problem is that it refers to the name of the constructor function. This is quickly becoming a discussion of function and operator expressions and the name property. It turns out that it is completely impossible to create a new named function at run time without using eval. Names can only be specified using the function operator function fnName(){} , and it is impossible to construct this piece of code dynamically without counting it. var fnExpression = function(){} results in the anonymous function assigned to the variable. The name property of the functions is immutable, so this is done. Using Function("arg1", "arg2", "return 'fn body';") can also create an anonymous function, even though it looks like eval.

It was mainly oversight in the JS specification (Brendan Eich stated that he regrets that he defines the display name as he did 10 years ago), and the decision was discussed for ES6. This will allow you to introduce more semantics to display the display name of the function for debugging tools, or perhaps an explicit way to install and configure it.

You now have one route: eval or some other form of late execution of custom code. (eval by any other name ...)

 function displayName(name, o){ var F = eval("1&&function "+name+"(){}"); F.prototype = o; return new F; } 

Only the function operator does not return from eval, but does 1 && fnStatement forces the thing to return the expression.

(Harmony Proxies also allows you to customize functions that provide names that you can configure without eval, but which are not used, with the exception of Node.js and Firefox currently).

I will remember here that all these "evil" functions that were imposed by Crockford and many others all have their place. eval , with , spreading the natives, all this allows you to use certain methods that are otherwise completely impossible, and it is wrong to use them when the case is right. Most likely, most people are not inclined to judge when this time will be right. In my opinion, using eval harmless in order to compensate for poor language semantics and tools while waiting for a solution, it is quite acceptable and will not do you any harm if you do not produce arbitrary code in this eval statement.

+13
source share

If I register an object, I see: Object { foo="bar", baz=function()} , so I do not understand your problem ...

In any case, instead of the Crockford function, you can use Object.create ():

 var P = { foo:'bar', baz: function(){ alert("bang"); } } var C = Object.create (P); 

console.log (C):

Object { foo="bar", baz=function()}

0
source share

All Articles