Copy link to clipboard
Copied
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
1 Correct answer
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
// 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, p
...
Explore related tutorials & articles
Copy link to clipboard
Copied
there's an old hackaround
You should work with prototype property:
Copy link to clipboard
Copied
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
// 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*/
);
Copy link to clipboard
Copied
Dear Dolce and Femke,
Many thanks, really useful.
@m h av72176891: 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?
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
Thank you so much, Femke, this is all really very helpful.
Copy link to clipboard
Copied
Thanks @femkeblanco, this helped me understand too! 🙂
- Mark
Copy link to clipboard
Copied
@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.
Copy link to clipboard
Copied
Thanks!
Copy link to clipboard
Copied
Super useful, Femke, thank you so much. I'm going to have a look at this. At the moment, I'm trying to wrap my head around how far to take OOP with ExtendScript. My kneejerk reflex is to write wrappers for some of the most common ExtendScript objects (say PathItem) but maybe with prototypal inheritance that approach is not so good?
Also, I'm wondering about how to handle actions on multiple objects. Say I have two instances of PathItem and I want to do a subtract (Boolean difference). Would I want to write a class to handle that? Or do I just fall back to procedural processing in the main thread, using a subtract menu command directly?
I'm aware this is probably more of a software architecture question that an OOP syntax question 🙂
Copy link to clipboard
Copied
I keep it simple. I use "classes" when I want to create many objects with similar properties, for example here. I use inheritance when I have many classes with similar functions, which is admittedly not common. I think there is some value in learning about prototypes, even if you don't use them, because you will come across cool scripts that do. Apart from that, there is the satisfaction of just understanding the concept of prototypes, which many Javascripters don't. (I can't help you with the question about actions. I don't think I have used actions in scripts.)
Copy link to clipboard
Copied
Hi @tomd75724979, a few notes:
1. I often write wrappers around Illustrator objects, but the one's I make aren't anything like a "sub-class" like you might make in other environments (or that Femke described). This may say more about me than anything generally.
2. I *almost never* use any form of inheritance—it just hasn't seemed useful for my projects. Again, this may not be a general experience for people. EDIT: oops, I mean to say I don't use inheritance aside from the built-in prototypal inheritance—I use that A LOT. 🙂
3. Inheritance and hierarchy has nothing *inherently* (no pun intended!) to do with object oriented programming. I find OOP *extremely* useful and yet I almost never need inheritance.
4. As @femkeblanco discusses, using prototypes is a good tool we have to express OOP principals.
With OOP we ask question such as "what does this object (by itself) know about?" and "what does this object (by itself) know how to do?" and "what are the relationships between this object and that object". These concepts are important: "What does the class know, versus what does each instance know?" and "What can the class do, versus what can each instance do?"
- Mark

