Skip to main content
Inspiring
January 20, 2024
Answered

[Q] OOP in ExtendScript / ECMAscript 3

  • January 20, 2024
  • 3 replies
  • 1125 views

Hi,

 

I am looking for some pointers and examples of what is possible in terms of OOP in ExtendScript. I'm not too lazy to Google, but Googling this info is quite hard as a lot of what pops up is for later versions of JavaScript in which OOP syntax is considerable different. I'm hoping for a clean example of what is possible in terms of inheritance and encapsulation with the state-of-the-art in 1999 🙂

 

For example, I notice that the following are not available:

Object.create()

class

 

I'm happily using this syntax:

 

function MyClass(myParameter) {
this.dataMember1 = ...;
this.dataMember2 = ...;

this.memberFunction1 = function(myParameter, myParameter) {
// do something
}

this.memberFunction2 = function(myParameter, myParameter) {
// do something
}

}

 

which works well and am interested how much further I can take this.

 

I read this:

https://alistapart.com/article/prototypal-object-oriented-programming-using-javascript/

 

which is helpful but also assumes  more modern Javascript than ExtendScript offers.

 

Any help greatly appreciated.

 

 

// Tom

 

 

This topic has been closed for replies.
Correct answer femkeblanco

Most, if not all, of what is in the link you posted works in ES3.  All you need is an Object.create polyfill.  You can add an

extend() function to emulate "class B extends A" in Java and ES6+ (@dolce5EC2 called it inheret()).
// polyfills
Object.create = function (o) {
    function F() {}
    F.prototype = o;
    return new F();
};
function extend(Child, Parent) {
    Child.prototype = Object.create(Parent.prototype);
    Child.prototype.constructor = Child;
}

// 1st class
var A = function (p1, p2) {
    this.p1 = p1;
    this.p2 = p2;
};
A.prototype.f1 = function () {
    return "f1 is called by " + this.p1 + this.p2;
};

// 2nd class (using inheritance)
var B = function (p1, p2) {
    // this.p1 = p1;
    // this.p2 = p2;
    // or, call super constructor, A:
    A.call(this, p1, p2);
};
extend(B, A);  // B inherits A's prototype

// creating objects
var a1 = new A("a", 1);
var b1 = new B("b", 1);

// accessing objects
alert(
    a1.f1()  /*f1 is called by object1*/
    + "\n" +
    b1.f1()  /*f1 is called by object2*/
);

3 replies

femkeblanco
Legend
January 22, 2024

@tomd75724979 @m1b You're welcome.  If you're interested, I found the crouse Ultimate JavaScript Part 2: Advanced Topics by Mosh Hamedani to be the easiest intro to OOP-like JavaScript.  The first part of the course is available on YouTube for free, but not the parts on prototypes and prototypal inheritance.  Still, you can check to see if it's not too basic for you.  The good thing about it is that it uses pre-ES6 JavaScript for the most part, which you can emulate with pollyfills (e.g. Object.create, Object.assign, etc), although there are some things ES3 just can't emulate. 

m1b
Community Expert
Community Expert
January 22, 2024

Thanks!

femkeblanco
femkeblancoCorrect answer
Legend
January 20, 2024

Most, if not all, of what is in the link you posted works in ES3.  All you need is an Object.create polyfill.  You can add an

extend() function to emulate "class B extends A" in Java and ES6+ (@dolce5EC2 called it inheret()).
// polyfills
Object.create = function (o) {
    function F() {}
    F.prototype = o;
    return new F();
};
function extend(Child, Parent) {
    Child.prototype = Object.create(Parent.prototype);
    Child.prototype.constructor = Child;
}

// 1st class
var A = function (p1, p2) {
    this.p1 = p1;
    this.p2 = p2;
};
A.prototype.f1 = function () {
    return "f1 is called by " + this.p1 + this.p2;
};

// 2nd class (using inheritance)
var B = function (p1, p2) {
    // this.p1 = p1;
    // this.p2 = p2;
    // or, call super constructor, A:
    A.call(this, p1, p2);
};
extend(B, A);  // B inherits A's prototype

// creating objects
var a1 = new A("a", 1);
var b1 = new B("b", 1);

// accessing objects
alert(
    a1.f1()  /*f1 is called by object1*/
    + "\n" +
    b1.f1()  /*f1 is called by object2*/
);
Inspiring
January 20, 2024

Dear Dolce and Femke,

 

Many thanks, really useful.

@17102471: I don't see you use the Object.create in your sample code. Why/when is the Object.create polyfill needed?

 

And these polyfills (Object.create and extend) do I only need them once? Where do you put them?

 

And in terms of best practices: do you put every class in a single file?

 

 

femkeblanco
Legend
January 20, 2024

Object.create is used in defining extend().  If you want to use it directly in the above example, you can use

B.prototype = Object.create(A.prototype);

instead of

extend(B, A);

and B will inherit the functions in A's prototype.

 

The pollyfills are used once and go right at the top of the script.  Or, you can put them in a separate file with any other pollyfills you regularly use (and access them with #include).  Java and JS conventions say that each class should be a separate file, but this can be ignored, of course.

Inspiring
January 20, 2024

there's an old hackaround
You should work with prototype property:

function ClassA() { }
ClassA.prototype.hello = function () {
$.writeln("o hi");
}
 
function ClassB() { }
 
 
inherit(ClassB, ClassA);
 
var b = new ClassB();
b.hello();
 
 
 
function inherit(childClass, parentClass) {
function F() { }
F.prototype = parentClass.prototype;
childClass.prototype = new F();
childClass.prototype.constructor = childClass;
childClass.super = parentClass.prototype;
}