0

I have read that Javascript's inheritance is prototypal.What does it mean?How can an object defined by the programer inherit the properties of a predefined object such as window ? For example I need the function eval() in my own class . How can it be achieved?

Jinu Joseph Daniel
  • 5,864
  • 15
  • 60
  • 90
  • Why would you inherit eval? Using eval in code is 99.99% of the time the wrong thing to do. – epascarello Jul 19 '11 at 14:50
  • For what purpose you need to *inherit* `eval`? The ECMAScript 5th Edition Specification made semantic changes to the behavior of `eval` when it's used in an indirect way -like in the way I think you are willing to use it, e.g. `myObj.eval`-, `eval` has no access to the caller's variable/lexical environment, it uses the global environment. Only direct `eval` calls have access to the caller lexical environment. – Christian C. Salvadó Jul 19 '11 at 15:07

3 Answers3

3

Setting aside the question of whether you should inherit from window, here's a simple example that demonstrates how to do it:

function Test() {
    // constructor code
}

Test.prototype = window;

var t = new Test();
t.eval();

When invoked using the new operator, the Test function creates a new instance of Test whose prototype is linked to the window object. A function's prototype can be any object.

Wayne
  • 59,728
  • 15
  • 131
  • 126
1

Protip: Don't use new for declaring objects. Object.create is the proper way to create JavaScript objects. It's supported in all modern browsers. For other browsers, a nice shim is at the bottom of this article:

http://javascript.crockford.com/prototypal.html

One problem with constructors that use 'new' is that if people accidentally call it like a regular function, it will make modifications on the global variable (i.e. window if in the browser) using the variable this, so this should only be reserved for prototype functions, and I prefer to use that instead of this

I personally use a style that supports new obj(), obj(), and obj.init(), which may be one extra function pointer, but I think it adds semantic meaning

function obj(){
    var that = Object.create(obj.prototype)
    //any constructor logic goes here
    return that
}
obj.prototype = Object.create(Superclass.prototype)

obj.init = obj //completely optional

//other function declarations

obj.prototype.someFunction = function(){
    //logic for someFunction
}
Richard Hoffman
  • 729
  • 3
  • 10
  • Is create() a part of standard Javascript Library? Or a part of frameworks like this?http://www.prototypejs.org/api/class/create – Jinu Joseph Daniel Jul 19 '11 at 16:18
  • @user822982, `Object.create` is part of the ECMAScript 5th Edition Specification, but it's [not completely emulable on ECMAScript 3](http://stackoverflow.com/questions/3830800/object-defineproperty-in-es5/3844768#3844768) implementations, the Crockford's `Object.create` shim cannot handle the second argument, to define properties with descriptors and it cannot create objects that inherit from `null`. – Christian C. Salvadó Jul 19 '11 at 16:27
0

What do you want exactly echieve to? Here is the simplest way (not the best) of prototype inheritance:

var obj1=new Object1Constructor();
var obj2=new Object2Constructor();

obj2.prototype=obj1;

It means that obj1 inherits all properties of obj2

I've forgot the main thing: eval==evil;

UPDATE: I've made mistakes in the code above. That is not inheritance. Here is updated code:

var Object1Constructor=function(){ // one object constuctor
    //properties definition goes here
}

var Object2Constructor=function(){ // another object constuctor
    //properties definition goes here
}

Object2Constructor.prototype=new Object1Constructor();

var obj=new Object2Constructor();

And that is inharitance. Now obj has properties defined in Object2Constructor and Object1Constructor - parent 'class'. See CMS's comment below. He is totally right.

Ruslan Polutsygan
  • 4,401
  • 2
  • 26
  • 37
  • 2
    The `prototype` property is only relevant to function objects -when used as Constructors-, you can't set the `[[Prototype]]` internal property of `obj2` like that, you're just creating a property named `"prototype"` on it (nothing about inheritance). The only way to *change* an already initialized object `[[Prototype]]` is through the non-standard and deprecated `__proto__` property. More info about `prototype` vs `[[Prototype]]`: [JavaScript prototype limited to functions ??](http://stackoverflow.com/questions/2111288/javascript-prototype-limited-to-functions/2111353) – Christian C. Salvadó Jul 19 '11 at 14:58
  • Yes. You are right. Please, look on updated code. Is it correct now? – Ruslan Polutsygan Jul 19 '11 at 15:36
  • 1
    yes, it looks good now, I would just set the `constructor` property of `Object2Constructor.prototype` back to `Object2Constructor` after replacing it, otherwise `obj.constructor` in your example, will refer to `Object1Constructor` (also, I would add semicolons also at the end of the function expressions -or use function definitions instead- but this isn't completely required). – Christian C. Salvadó Jul 19 '11 at 16:33