fix the discrepancy between JS engines used by Firefox and Opera

Y

Yan Huang

Hi,

Following is a repost from the group Opera.general. Hope someone can
help me out. Many thanks!

I want to some JavaScript code in Opera that uses methods such as
Object.prototype.toSource, Function.prototype.toSource, ..., and
Array.prototype.toSource etc, which are specific to Firefox's
Spidermonkey implementation. Also, the Function.prototype.toString
method in Opera is also different from that in Firefox. Anyone has an
idea how to adapt my script code to make it behave the same as in
Spidermonkey?

In addition, I have a related more general question on JavaScript's
reflection capability. For example, Function.prototype.toSource method
meets important reflection needs. Anyone knows more pointers on this
topic?

Thanks,
Yan Huang
 
J

Jeremy J Starcher

Hi,

Following is a repost from the group Opera.general. Hope someone can
help me out. Many thanks!

I want to some JavaScript code in Opera that uses methods such as
Object.prototype.toSource, Function.prototype.toSource, ..., and
Array.prototype.toSource etc, which are specific to Firefox's
Spidermonkey implementation. Also, the Function.prototype.toString
method in Opera is also different from that in Firefox. Anyone has an
idea how to adapt my script code to make it behave the same as in
Spidermonkey?

In addition, I have a related more general question on JavaScript's
reflection capability. For example, Function.prototype.toSource method
meets important reflection needs. Anyone knows more pointers on this
topic?

Thanks,
Yan Huang

You might want to look at a JSON library[1]. Most of them provide
something similar to Object.prototype.toSource, and
Array.prototype.toSource, they might be called or used differently.

Function.prototype.toSource ... For this you could look at
Function.prototype.toString. However, the results are very
implementation specific and do not always yield correct or usable source
code.

[1] http://json.org/
 
G

George

Following is a repost from the group Opera.general. Hope someone can
help me out. Many thanks!
I want to some JavaScript code in Opera that uses methods such as
Object.prototype.toSource, Function.prototype.toSource, ..., and
Array.prototype.toSource etc, which are specific to Firefox's
Spidermonkey implementation. Also, the Function.prototype.toString
method in Opera is also different from that in Firefox. Anyone has an
idea how to adapt my script code to make it behave the same as in
Spidermonkey?
In addition, I have a related more general question on JavaScript's
reflection capability. For example, Function.prototype.toSource method
meets important reflection needs. Anyone knows more pointers on this
topic?
Thanks,
Yan Huang

You might want to look at a JSON library[1].  Most of them provide
something similar to  Object.prototype.toSource, and
Array.prototype.toSource, they might be called or used differently.

Function.prototype.toSource ... For this you could look at
Function.prototype.toString.  However, the results are very
implementation specific and do not always yield correct or usable source
code.

[1]  http://json.org/

Thank you for your suggestions. But I am a little confused about the
JSON library link
you gave me. It seems that the libraries on that page are all about
JSON parsing and de-parsing.
How is that relevant to implement Object[Array].prototype.toSource?

In addition, in Opera the Function.prototype.toString method merely
returns trivial results where
the function body is always "[native code]" even it is a user defined
function.

Thanks,
Yan Huang
 
G

Garrett Smith

Yan said:
Hi,

Following is a repost from the group Opera.general. Hope someone can
help me out. Many thanks!

I want to some JavaScript code in Opera that uses methods such as
Object.prototype.toSource, Function.prototype.toSource, ..., and
Array.prototype.toSource etc, which are specific to Firefox's
Spidermonkey implementation. Also, the Function.prototype.toString
method in Opera is also different from that in Firefox. Anyone has an
idea how to adapt my script code to make it behave the same as in
Spidermonkey?

Avoid relying on any of those methods for program behavior. Look for
another strategy to solve the problem.
 
S

slebetman

You might want to look at a JSON library[1].  Most of them provide
something similar to  Object.prototype.toSource, and
Array.prototype.toSource, they might be called or used differently.
Function.prototype.toSource ... For this you could look at
Function.prototype.toString.  However, the results are very
implementation specific and do not always yield correct or usable source
code.

Thank you for your suggestions. But I am a little confused about the
JSON library link
you gave me. It seems that the libraries on that page are all about
JSON parsing and de-parsing.
How is that relevant to implement Object[Array].prototype.toSource?

JSON stands for Javascript Object Notation -- meaning format of the
source code for object literals used by javascript. So if you want a
string representation of a javascript object use the JSON.stringify()
function in the json2.js library:

JSON.stringify(Object) instead of Object.prototype.toSource
 
J

Jorge


Thank you for your suggestions. But I am a little confused about the
JSON library link
you gave me. It seems that the libraries on that page are all about
JSON parsing and de-parsing.
How is that relevant to implement Object[Array].prototype.toSource?
(...)

//Load the JSON lib
if (!JSON) {
document.body.appendChild(
document.createElement(
'script')).src="http://www.JSON.org/json2.js";
}

(function (o) {

alert(o.toString());
// '[object Object]'

alert(JSON.stringify(o));
// '{"a":1,"b":"2"}'

alert(o.toSource());
// '({a:1, b:"2"})' || TypeError: 'o.toSource' is not a function.

})({a:1, b:"2"});

Augment the Object.prototype like this:

if (!Object.prototype.toSource && JSON && JSON.stringify) {
Object.prototype.toSource= function () {
return JSON.stringify(this);
};
}

to emulate FF's .toSource(), although as you have seen above the
output texts would be slightly different.
 
J

Jorge

(...)
No, JSON employs a subset of javascript's object literal notation. In
JSON the object's property names must take the form of string literals
(rather than Identifiers or numeric literals) and the values of
properties cannot include functions.



But don't expect to see any methods appearing in that representation.

Well, sort of... :

//Load the JSON lib
if (!JSON) {
document.body.appendChild(
document.createElement(
'script')).src="http://www.JSON.org/json2.js";
}

o= {a:1, b:"2", c: function () { alert("Hi !"); } };

function reviver (key, value, tag) {
tag= "***FUNCTION:";
if ((typeof value === "string") && (value.indexOf(tag) === 0)) {
value= eval("("+ atob(value.substr(tag.length))+ ")");
}
return value;
}

function replacer (key, value) {
if (typeof value === "function") {
value= "***FUNCTION:"+ btoa(value);
}
return value;
}

alert(txt= JSON.stringify(o, replacer));
o= JSON.parse(txt, reviver);
o.c();
//alerts "Hi !"

:)
 
J

Jorge

Well, sort of... :

//Load the JSON lib
if (!JSON) {
  document.body.appendChild(
  document.createElement(
  'script')).src="http://www.JSON.org/json2.js";

}

o= {a:1, b:"2", c: function () { alert("Hi !"); } };

function reviver (key, value, tag) {
  tag= "***FUNCTION:";
  if ((typeof value === "string") && (value.indexOf(tag) === 0)) {
    value= eval("("+ atob(value.substr(tag.length))+ ")");
  }
  return value;

}

function replacer (key, value) {
  if (typeof value === "function") {
    value= "***FUNCTION:"+ btoa(value);
  }
  return value;

}

alert(txt= JSON.stringify(o, replacer));
o= JSON.parse(txt, reviver);
o.c();
//alerts "Hi !"

:)

You might need this too:

if (typeof window.btoa === "undefined") {
window.btoa= function (input, b64, output, chr1, chr2, chr3, enc1,
enc2, enc3, enc4, i) {

// Modificado por (e-mail address removed)
// Code was written by Tyler Akins and is placed in the public
domain
// It would be nice if you left this header. http://rumkin.com

b64=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
output = "";
i = 0;

do {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);

enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;

if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}

output = output + b64.charAt(enc1) + b64.charAt(enc2) +
b64.charAt(enc3) + b64.charAt(enc4);
} while (i < input.length);

return output;
};
}

if (typeof window.atob === "undefined") {
window.atob= function (input, output, chr1, chr2, chr3, enc1, enc2,
enc3, enc4, i) {

// Modificado por (e-mail address removed)
// Code was written by Tyler Akins and is placed in the public
domain
// It would be nice if you left this header. http://rumkin.com

b64=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
output = "";
i = 0;

// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

while (i < input.length) {
enc1 = b64.indexOf(input.charAt(i++));
enc2 = b64.indexOf(input.charAt(i++));
enc3 = b64.indexOf(input.charAt(i++));
enc4 = b64.indexOf(input.charAt(i++));

chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;

output = output + String.fromCharCode(chr1);

if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}

return output;
};
}
 
J

Jorge

You might need this too:

if (typeof window.btoa === "undefined") {
  window.btoa= function (input, b64, output, chr1, chr2, chr3, enc1,
enc2, enc3, enc4, i) {

    // Modificado por (e-mail address removed)
    // Code was written by Tyler Akins and is placed in the public
domain
    // It would be nice if you left this header.  http://rumkin.com

    b64=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    output = "";
    i = 0;

    do {
      chr1 = input.charCodeAt(i++);
      chr2 = input.charCodeAt(i++);
      chr3 = input.charCodeAt(i++);

      enc1 = chr1 >> 2;
      enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
      enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
      enc4 = chr3 & 63;

      if (isNaN(chr2)) {
        enc3 = enc4 = 64;
      } else if (isNaN(chr3)) {
        enc4 = 64;
      }

      output = output + b64.charAt(enc1) + b64.charAt(enc2) +
      b64.charAt(enc3) + b64.charAt(enc4);
    } while (i < input.length);

    return output;
  };

}

if (typeof window.atob === "undefined") {
  window.atob= function (input, output, chr1, chr2, chr3, enc1, enc2,
enc3, enc4, i) {

    // Modificado por (e-mail address removed)
    // Code was written by Tyler Akins and is placed in the public
domain
    // It would be nice if you left this header.  http://rumkin.com

    b64=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    output = "";
    i = 0;

    // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
    input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

    while (i < input.length) {
      enc1 = b64.indexOf(input.charAt(i++));
      enc2 = b64.indexOf(input.charAt(i++));
      enc3 = b64.indexOf(input.charAt(i++));
      enc4 = b64.indexOf(input.charAt(i++));

      chr1 = (enc1 << 2) | (enc2 >> 4);
      chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
      chr3 = ((enc3 & 3) << 6) | enc4;

      output = output + String.fromCharCode(chr1);

      if (enc3 != 64) {
        output = output + String.fromCharCode(chr2);
      }
      if (enc4 != 64) {
        output = output + String.fromCharCode(chr3);
      }
    }

    return output;
  };

}

One more thing...

Note that btoa(sourceText) fails if sourceText contains any character
whose charCode is > 255, e.g. btoa("€") doesn't work, nor btoa
("\u20ac").
 
J

Jorge

One more thing...

Note that btoa(sourceText) fails if sourceText contains any character
whose charCode is > 255, e.g. btoa("€") doesn't work, nor btoa
("\u20ac").

One more thing #2 ...

Native code can't be stringified, therefore this:

o= {f: alert};

Would fail. Instead, wrap them like this:

o= {f: function (p) { alert(p); }};

OTOH, I can't see a reason why you'd ever need to stringify a native
function.
 
G

George

Thank you so much! But, a few more points below ...

OTOH, I can't see a reason why you'd ever need to stringify a native
function.

I don't quite need to stringify native functions/methods.

What I really need to do, is to mimic the behavior of Firefox's JS
engine's behavior about *.prototype.toSource method, in a browser
(such as Opera) that doesn't support the toSource-family of methods.
e.g.,

function zero(){return 0;}
zero.toSource(); // return function zero() {return 0;}

var identity = new Function('x', 'return x;');
identity.toSource(); // return (function anonymous(x) {return x;})

var obj={a:1, f:function(_a){a=_a;}};
obj.toSource(); // return ({a:1, f:(function (_a) {a = _a;})})

var arr = [1,2,function(){}];
arr.toSource(); // return [1, 2, (function () {})]

In the example you gave, the starting point seems always to be an
object literal in valid JSON format. But I have to cope with
arbitrary script code, especially written by other programmers.
Imagine what I get is just the *resultant browser environment* of
the execution of the following 4 lines of script,

function zero(){return 0;}
var identity = new Function('x', 'return x;');
var obj={a:1, f:function(_a){a=_a;}};
var arr = [1,2,function(){}];

I intend the following 4 lines of code produce the desired output in
Opera, as in Firefox.
zero.toSource(); // return function zero() {return 0;}
identity.toSource(); // return (function anonymous(x) {return x;})
obj.toSource(); // return ({a:1, f:(function (_a) {a = _a;})})
arr.toSource(); // return [1, 2, (function () {})]

Your suggested solution (by defining a property
Object.prototype.toSource myself) seem to work with Object and Array
objects, but
I still don't see how it could work with Function objects. Can you
give more pointers about that?

Thanks,
--Yan
 
G

George

One more point to add, I am not developing web apps. I am trying to do
automatic JS program analysis.
Hope this helps explain my weird needs.

-- Yan Huang

Thank you so much! But, a few more points below ...

On Oct 8, 12:36 pm, Jorge <[email protected]> wrote:
OTOH, I can't see a reason why you'd ever need to stringify a native
function.

I don't quite need to stringify native functions/methods.

What I really need to do, is to mimic the behavior of Firefox's JS
engine's behavior about *.prototype.toSource method, in a browser
(such as Opera) that doesn't support the toSource-family of methods.
e.g.,

function zero(){return 0;}
zero.toSource();    // return function zero() {return 0;}

var identity = new Function('x', 'return x;');
identity.toSource();     // return (function anonymous(x) {return x;})

var obj={a:1, f:function(_a){a=_a;}};
obj.toSource();       // return ({a:1, f:(function (_a) {a = _a;})})

var arr = [1,2,function(){}];
arr.toSource();       // return [1, 2, (function () {})]

In the example you gave, the starting point seems always to be an
object literal in valid JSON format. But I have to cope with
arbitrary script code, especially written by other programmers.
Imagine what I get is just the *resultant browser environment* of
the execution of the following 4 lines of script,

function zero(){return 0;}
var identity = new Function('x', 'return x;');
var obj={a:1, f:function(_a){a=_a;}};
var arr = [1,2,function(){}];

I intend the following 4 lines of code produce the desired output in
Opera, as in Firefox.
zero.toSource();      // return function zero() {return 0;}
identity.toSource();  // return (function anonymous(x) {return x;})
obj.toSource();       // return ({a:1, f:(function (_a) {a = _a;})})
arr.toSource();       // return [1, 2, (function () {})]

Your suggested solution (by defining a property
Object.prototype.toSource myself) seem to work with Object and Array
objects, but
I still don't see how it could work with Function objects. Can you
give more pointers about that?

Thanks,
--Yan


 
J

Jorge

Thank you so much! But, a few more points below ...

On Oct 8, 12:36 pm, Jorge <[email protected]> wrote:
OTOH, I can't see a reason why you'd ever need to stringify a native
function.

I don't quite need to stringify native functions/methods.

What I really need to do, is to mimic the behavior of Firefox's JS
engine's behavior about *.prototype.toSource method, in a browser
(such as Opera) that doesn't support the toSource-family of methods.
e.g.,

function zero(){return 0;}
zero.toSource();    // return function zero() {return 0;}

var identity = new Function('x', 'return x;');
identity.toSource();     // return (function anonymous(x) {return x;})

var obj={a:1, f:function(_a){a=_a;}};
obj.toSource();       // return ({a:1, f:(function (_a) {a = _a;})})

var arr = [1,2,function(){}];
arr.toSource();       // return [1, 2, (function () {})]

In the example you gave, the starting point seems always to be an
object literal in valid JSON format. But I have to cope with
arbitrary script code, especially written by other programmers.
Imagine what I get is just the *resultant browser environment* of
the execution of the following 4 lines of script,

function zero(){return 0;}
var identity = new Function('x', 'return x;');
var obj={a:1, f:function(_a){a=_a;}};
var arr = [1,2,function(){}];

I intend the following 4 lines of code produce the desired output in
Opera, as in Firefox.
zero.toSource();      // return function zero() {return 0;}
identity.toSource();  // return (function anonymous(x) {return x;})
obj.toSource();       // return ({a:1, f:(function (_a) {a = _a;})})
arr.toSource();       // return [1, 2, (function () {})]

Your suggested solution (by defining a property
Object.prototype.toSource myself) seem to work with Object and Array
objects, but
I still don't see how it could work with Function objects. Can you
give more pointers about that?

Functions are objects and as such inherit from Object.prototype.
I've tested this in Safari 4, it (sort-of) works :)

//Load the JSON lib
if (!JSON) {
document.body.appendChild(
document.createElement(
'script')).src="http://www.JSON.org/json2.js";
}

delete Object.prototype.toSource;

if (!Object.prototype.toSource && JSON && JSON.stringify) {
Object.prototype.toSource= function (txt) {
function replacer (key, value, n) {
if (typeof value === "function") {
n= !((value.name === "") || (value.name === "anonymous"));
value= "***FuNcTiOn"+ (n?"":"(")+ value+ (n?"":")")+
"nOiTcNuF***";
}
return value;
}
txt= JSON.stringify(this, replacer)
return txt.replace(/("\*\*\*FuNcTiOn)|(nOiTcNuF\*\*\*")/g,"");
};
}

function zero () { return 0; }
var identity = new Function('x', 'return x;');
var obj= { a:1, f:function (_a) { a=_a; } };
var arr = [1, 2, function () { } ];

alert(zero.toSource());
// return function zero() { return 0; }

alert(identity.toSource());
// return (function anonymous(x) {return x;})

alert(obj.toSource());
// return ({a:1, f:(function (_a) {a = _a;})})

alert(arr.toSource());
// return [1, 2, (function () { } )]
 
B

Bart Lateur

George said:
What I really need to do, is to mimic the behavior of Firefox's JS
engine's behavior about *.prototype.toSource method, in a browser
(such as Opera) that doesn't support the toSource-family of methods.
e.g.,

I wonder why you don't try to get by with .toString(). Here are results
of tests at the console of Firebug Lite
(http://getfirebug.com/lite.html), in Opera:
function zero(){return 0;}
zero.toSource(); // return function zero() {return 0;}

function zero(){return 0;}
zero.toString();
"function zero(){return 0;}"
var identity = new Function('x', 'return x;');
identity.toSource(); // return (function anonymous(x) {return x;})

var identity = new Function('x', 'return x;');
identity.toString();
"function (x\n){return x;\n}"
var obj={a:1, f:function(_a){a=_a;}};
obj.toSource(); // return ({a:1, f:(function (_a) {a = _a;})})

var obj={a:1, f:function(_a){a=_a;}};
obj.toString();
"[object Object]"

Okay, so that's a failure.
var arr = [1,2,function(){}];
arr.toSource(); // return [1, 2, (function () {})]

var arr = [1,2,function(){}];
arr.toString();
"1,2,function(){}"

Uh, almost a success, except it omits the array brackets.

If you recursively step through data structures, effectively
JSON-serializing them, and use toString() on functions, you ought to get
really close to what you want.

Actually, useless trivia time, Javascript Tidy
(http://www.howtocreate.co.uk/tutorials/jsexamples/JSTidy.html) uses
toString() to reformat Javascript code. It actually works better in
Opera than in Firebug because Firefox shows anonymous functions as one
long line, and Opera formats the code tidily.
 
J

Jeremy J Starcher

One more point to add, I am not developing web apps. I am trying to do
automatic JS program analysis.
Hope this helps explain my weird needs.

-- Yan Huang

In which case, I would recommend a totally different approach and I would
parse the raw source code myself, similar to what JS lint does.

Function.prototype.toString() and Function.prototype.toSource() cannot be
relied upon to return code equivalent to the original code. I wish that
wasn't the case, but it is.
 
G

George

Thanks! You are my magician.

---Yan
Thank you so much! But, a few more points below ...
I don't quite need to stringify native functions/methods.
What I really need to do, is to mimic the behavior of Firefox's JS
engine's behavior about *.prototype.toSource method, in a browser
(such as Opera) that doesn't support the toSource-family of methods.
e.g.,
function zero(){return 0;}
zero.toSource();    // return function zero() {return 0;}
var identity = new Function('x', 'return x;');
identity.toSource();     // return (function anonymous(x) {return x;})
var obj={a:1, f:function(_a){a=_a;}};
obj.toSource();       // return ({a:1, f:(function (_a) {a = _a;})})
var arr = [1,2,function(){}];
arr.toSource();       // return [1, 2, (function () {})]
In the example you gave, the starting point seems always to be an
object literal in valid JSON format. But I have to cope with
arbitrary script code, especially written by other programmers.
Imagine what I get is just the *resultant browser environment* of
the execution of the following 4 lines of script,
function zero(){return 0;}
var identity = new Function('x', 'return x;');
var obj={a:1, f:function(_a){a=_a;}};
var arr = [1,2,function(){}];
I intend the following 4 lines of code produce the desired output in
Opera, as in Firefox.
zero.toSource();      // return function zero() {return 0;}
identity.toSource();  // return (function anonymous(x) {return x;})
obj.toSource();       // return ({a:1, f:(function (_a) {a = _a;})})
arr.toSource();       // return [1, 2, (function () {})]
Your suggested solution (by defining a property
Object.prototype.toSource myself) seem to work with Object and Array
objects, but
I still don't see how it could work with Function objects. Can you
give more pointers about that?

Functions are objects and as such inherit from Object.prototype.
I've tested this in Safari 4, it (sort-of) works :)

//Load the JSON lib
if (!JSON) {
 document.body.appendChild(
 document.createElement(
 'script')).src="http://www.JSON.org/json2.js";

}

delete Object.prototype.toSource;

if (!Object.prototype.toSource && JSON && JSON.stringify) {
 Object.prototype.toSource= function (txt) {
  function replacer (key, value, n) {
   if (typeof value === "function") {
    n= !((value.name === "") || (value.name === "anonymous"));
    value= "***FuNcTiOn"+ (n?"":"(")+ value+ (n?"":")")+
"nOiTcNuF***";
   }
   return value;
  }
  txt= JSON.stringify(this, replacer)
  return txt.replace(/("\*\*\*FuNcTiOn)|(nOiTcNuF\*\*\*")/g,"");
 };

}

function zero () { return 0; }
var identity = new Function('x', 'return x;');
var obj= { a:1, f:function (_a) { a=_a; } };
var arr = [1, 2, function () { } ];

alert(zero.toSource());
// return function zero() { return 0; }

alert(identity.toSource());
// return (function anonymous(x) {return x;})

alert(obj.toSource());
// return ({a:1, f:(function (_a) {a = _a;})})

alert(arr.toSource());
// return [1, 2, (function () { } )]
 
G

George

Thank you guys. I appreciate it.

-- Yan Huang
George said:
What I really need to do, is to mimic the behavior of Firefox's JS
engine's behavior about *.prototype.toSource method, in a browser
(such as Opera) that doesn't support the toSource-family of methods.
e.g.,

I wonder why you don't try to get by with .toString(). Here are results
of tests at the console of Firebug Lite
(http://getfirebug.com/lite.html), in Opera:
function zero(){return 0;}
zero.toSource();    // return function zero() {return 0;}

function zero(){return 0;}
zero.toString();
        "function zero(){return 0;}"
var identity = new Function('x', 'return x;');
identity.toSource();     // return (function anonymous(x) {return x;})

var identity = new Function('x', 'return x;');
identity.toString();
        "function (x\n){return x;\n}"
var obj={a:1, f:function(_a){a=_a;}};
obj.toSource();       // return ({a:1, f:(function (_a) {a = _a;})})

var obj={a:1, f:function(_a){a=_a;}};
obj.toString();    
        "[object Object]"

Okay, so that's a failure.
var arr = [1,2,function(){}];
arr.toSource();       // return [1, 2, (function () {})]

var arr = [1,2,function(){}];
arr.toString();      
        "1,2,function(){}"

Uh, almost a success, except it omits the array brackets.

If you recursively step through data structures, effectively
JSON-serializing them, and use toString() on functions, you ought to get
really close to what you want.

Actually, useless trivia time, Javascript Tidy
(http://www.howtocreate.co.uk/tutorials/jsexamples/JSTidy.html) uses
toString() to reformat Javascript code. It actually works better in
Opera than in Firebug because Firefox shows anonymous functions as one
long line, and Opera formats the code tidily.
 
T

Thomas 'PointedEars' Lahn

George said:
Thanks! You are my magician.

Because miraculously he lets appear properties in for-in iteration that
weren't there before, which would significantly modify the behavior of any
source code that employs this langauge feature, and thus add a significant
bias into the results of your code analysis?


PointedEars
 
J

Jorge

Because miraculously he lets appear properties in for-in iteration that
weren't there before, which would significantly modify the behavior of any
source code that employs this langauge feature, and thus add a significant
bias into the results of your code analysis?

if (o.hasOwnProperty(property)) { ...
 
T

Thomas 'PointedEars' Lahn

Jorge said:
if (o.hasOwnProperty(property)) { ...

As you should know if you followed the discussions here closely, I am well
aware of the workaround. However, the people that have written the source
code to be analyzed neither necessarily are aware of it, nor would they have
a compelling need to make use of it even if they were aware of it.

Besides, Object.prototype.hasOwnProperty() would be another property that
might need to be emulated for this to be cross-browser, by which we would
have to solve a chicken-and-the-egg problem.


PointedEars
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top