0

I recently started using prototyping for a project. It is one of my first times using prototyping, so still finding my legs :) I come from an object oriented background, so excuse me if some of my terminology is not correct.

One of my main reasons for using it is to create a scoping framework for the project, to avoid any conflicts later on. I also use it to allow me to create objects spread over several files.

I am however having trouble with something.

I declare my base "class" in one file. In another file, I then declare an extension to the class. In this extension I declare a function, which I then try to call from the base class. Lastly I declare an instance of the extension inside the base class to allow me to call the extended functions from the base class.

When I try and create the instance, however, I get the following error:

SCRIPT445: Object doesn't support this action leave.js, line 2 character 5

Here is a snippet of my code:

leave.js

var _LEAVE = function () {
    this.WORK_LIST = new this._WORK_LIST();
}

worklist.js

_LEAVE.prototype._WORK_LIST = function (params) {
    var Render = function(){
         ...
    }
}

Any suggestions about what I am doing wrong and how to fix it would be greatly appreciated.

glortho
  • 13,120
  • 8
  • 49
  • 45
phunder
  • 1,607
  • 3
  • 17
  • 33
  • If it matters. `render()` is private because it's declared with var and not `this.render`, a prototype, or returned. So if you're trying to access it from `_LEAVE` you will have difficulties. – Owen Allen Nov 09 '12 at 03:21
  • 1. Prototype-based OOP is still OOP, but there are no classes; you could say "an object type" or "a kind of object" instead. 2. You leave us to guess which code causes the problem, i. e. how you call what you declared above. 3. Which implementation (JavaScript, JScript, V8, ...) are you using? Server-side or client-side? – PointedEars Nov 09 '12 at 03:23
  • You should add more code. There isn't really enough there to reveal the error. – Greg Nov 09 '12 at 03:24
  • @Nucleon There is no `render()`, there is `Render` (case-sensitive), and there is no indication that it is accessed in `_LEAVE()`. Either the problem is in calling `_LEAVE()` or in the definition of the function assigned to `Render`. The difficulties that you mention correctly are this: direct access to `Render` from outside `_WORK_LIST()` is *impossible* (in a standards-compliant implementation, so all fairly recent ones). – PointedEars Nov 09 '12 at 03:29

2 Answers2

3

Alright, firstly if you don't understand prototype-based inheritance then I suggest that you learn about it. It's really simple actually.

Secondly, and please don't take this in the wrong way - your code abhors me. I understand that you've come from a classical background and I respect the effort you're making. However, truly speaking I wouldn't want to read your code even if I was paid to.

This is what I would have done (correct me if my program isn't what you're looking for, but I really don't know what's happening in your code):

// baseClass.js

function BaseClass() {                       // class BaseClass
    var extendedObject = new Extension;
}

// extension.js

Extension.prototype = new BaseClass;         // Extension extends BaseClass
Extension.prototype.constructor = Extension; // reset the constructor property

function Extension() {                       // class Extension
    // some private variables

    var privateVar = null;
    function privateFunction() {}

    // some public properties

    this.publicVar = null;
    this.publicFunction = function () {};
}

In addition, since you're from a classical background it may help you to write code that's more in line with the classical style of inheritance. Read this answer. It will help you a lot.

Edit: Using my script you can create classes in JavaScript as follows.

baseClass.js:

/*
    class BaseClass {
        var extension;

        function constructor() {
            extension = new Extension;
        }
    }
*/

var BaseClass = new Class(function () {
    var extension;

    function constructor() {
        extension = new Extension;
    }

    return constructor;
});

extension.js:

/*
    class Extension extends BaseClass {
        var secret;

        function constructor() {
            secret = null;
        }

        this.getSecret = function () {
            return secret;
        };

        this.setSecret = function (newSecret) {
            secret = newSecret;
        };
    }
*/

var Extension = new Class(function () {
    var secret;

    function constructor() {
        secret = null;
    }

    this.getSecret = function () {
        return secret;
    };

    this.setSecret = function (newSecret) {
        secret = newSecret;
    };

    return constructor;
}, BaseClass);

You may tinker with the fiddle.

Community
  • 1
  • 1
Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299
0

If you haven't instantiated _LEAVE with new, this will refer to the window object. Try this instead:

var _LEAVE = function () {
    this.WORK_LIST = new this._WORK_LIST();
}

_LEAVE.prototype._WORK_LIST = function (params) {
    var Render = function(){
         ...
    }
}

console.log(new _LEAVE());
glortho
  • 13,120
  • 8
  • 49
  • 45