Copy link to clipboard
Copied
Hi,
I'm trying to implement some functions to manipulate Arrays more easily, like I would do with other programming languages (Array.indexOf() does exist in Javascript, but seems to be missing from ExtendScript).
First, I tried to add those functions using Array.prototype; here is what I did for two of those functions:
Array.prototype.indexOf = function (value)
{
for (var i = 0;i<this.length;i++)
{
if (this == value) return i;
}
return -1;
}
Array.prototype.removeDuplicates = function ()
{
var removed = [];
for (var i = 0;i<this.length-1;i++) {
for (var j=i+1;j<this.length;j++) {
if (this == this
) { removed.push(this.splice(j,)1);
}
}
}
return removed;
}
It seemed to work well, but I found out that it breaks this kind of loop:
for (var i in array) {
alert(array);
}
The loop goes through array values, and continues beyond array.length with the functions added to the prototype.
As explained here, I found a workaround, using Object.defineProperty() instead of implementing functions in Array.proptotype
Object.defineProperty(Array.prototype, "indexOf", {
enumerable: false,
value: function(value) {
for (var i = 0;i<this.length;i++)
{
if (this == value) return i;
}
return -1;
}
});
But..... Object.defineProperty() is missing in ExtendScript too!
I don't know what to try next... Any idea?
Thanks!
1 Correct answer
The primary reason that some of those functions do not exist, is because ExtendScript is based on the ECMA-262 standard. Very old Javascript, and I believe not all of it is implemented.
Pg. 3 of the CS6 scripting guide (only full written guide Adobe has at the moment) After Effects Developer Center | Adobe Developer Connection:
The ExtendScript language
"After Effects scripts use the Adobe ExtendScript language, which is an extended form of JavaScript used by several Adobe applications, including
...Copy link to clipboard
Copied
The primary reason that some of those functions do not exist, is because ExtendScript is based on the ECMA-262 standard. Very old Javascript, and I believe not all of it is implemented.
Pg. 3 of the CS6 scripting guide (only full written guide Adobe has at the moment) After Effects Developer Center | Adobe Developer Connection:
The ExtendScript language
"After Effects scripts use the Adobe ExtendScript language, which is an extended form of JavaScript used by several Adobe applications, including Photoshop, Illustrator, and InDesign. ExtendScript implements the JavaScript language according to the ECMA-262 specification. The After Effects scripting engine supports the 3rd Edition of the ECMA-262 Standard, including its notational and lexical conventions, types, objects, expressions, and statements. ExtendScript also implements the E4X ECMA-357 specification, which defines access to data in XML format."
While I know a lot of developers have done prototyping, I've found it to be troublesome personally, especially if your code travels outside of your machine. I've just simply made standalone functions for all of my scripts. It has been easier to reuse code and create some (not all) of the missing functions that would be nice to have from current day Javascript.
Copy link to clipboard
Copied
Thanks!
I should have started by reading the guide...
I finally used standalone methods as you described, but I believe prototyping well made would have made things easier for further dev.
I usually get confused about what methods are implemented or not, in what language, and I'm used to implement what I miss most when it does not exists. This example, Array object missing indexOf method, has annoyed me for so long!
Copy link to clipboard
Copied
nicoDuduf wrote:
It seemed to work well, but I found out that it breaks this kind of loop:
- for (var i in array) {
- alert(array);
- }
for (var i in array) { alert(array); }
Technically it is not breaking this loop. The loop is just used in a wrong way.
See http://stackoverflow.com/questions/500504/why-is-using-for-in-with-array-iteration-such-a-bad-idea‌:
"The for-in
statement by itself is not a "bad practice", however it can be mis-used, for example, to iterate over arrays or array-like objects.
The purpose of the for-in
statement is to enumerate over object properties, this statement will go up in the prototype chain, enumerating also inherited properties, thing that sometimes is not desired."
However, since other script authors may use loops in such a wrong way, using prototype on things like Array or Object in your script might break scripts by other authors.
Hence, as David suggested, you better don't use it. I only use prototype for my own object types.
Copy link to clipboard
Copied
Thanks for this answer,
I found that, that's why I tried
- Object.defineProperty()
with the statement "enumerable:false" which makes for-in loops to not iterate through properties added this way. This could have worked, if only Object.defineProperty was implemented in extendScript.
It is little known that the for-in loop is not meant to iterate through Arrays, and a looooot of developpers use it this way, as it seems quicker than writing the whole "for (i;i<;i++)" loop...
Copy link to clipboard
Copied
Also you can write it like this:
for (var i in array) {
if (array.hasOwnProperty(i)) {
alert(array);
}
}

