Объект Javascript получает код как строку

Во-первых, я сожалею, если это дубликат, но каждый раз, когда я googled для "объекта" и "кода", я получал учебные страницы.

Я хочу знать, есть ли простой способ получить код, связанный с объектом. Что-то вроде

function A(){
  this.name = 'Kaiser Sauze';
}
a = new A();
console.log(a.displayCode());
//OUTPUT
"function A(){ this.name = 'Kaiser Sauze';}"

Я хочу, чтобы иметь возможность просматривать код, изменять его и перезагружать функцию, все из браузера. Я хотел знать, есть ли какой-то способ сделать это, или если мне нужно настроить насос, сделав что-то вроде этого:

function A(){
  this.name = 'Kaiser Sauze';
  this.code = "function A(){ this.name = 'Kaiser Sauze';}"
}

то каждый раз, когда пользователь загружает текстовый редактор для просмотра this.code, я подключаю onchange к обновлению this.code.

ИЗМЕНИТЬ

оказывается, что янки предложил простое решение этой

function A(x){
  this.x = x ;
}
console.log(A.toString());
//OUTPUT
"function A(x){
  this.x = x ;
}"

но в моей реализации переменная 'x' может быть функцией (фактически сложным объектом с переменными, функциями и вспомогательными объектами, которые я смешиваю посредством вызова dojo.mixin), поэтому я действительно хочу, чтобы знать код при создании экземпляра, что-то вроде этого

function A(x){
  this.x = x ;
}
var a = new A(function(){/*DO SOMETHING*/);
console.log(a.toString());
//OUTPUT
"var a = new A(function(){/*DO SOMETHING*/);"

но, как большинство из вас уже знает, все, что получает результат, похоже на "Object". Я почти нашел способ обойти это, поставив инициализацию в такой функции

function A(x){
  this.x = x ;
}
function _A(){
  var a = new A(function(){/*DO SOMETHING*/);
}
console.log(_A.toString());
//OUTPUT
"function _A(){
  var a = new A(function(){/*DO SOMETHING*/);
}"

но это сбивает с толку, а затем я должен войти и начать синтаксический разбор строки, которую я не хочу делать.

EDIT: Причина, по которой я прошу все это, - это b/c. Я хочу сделать код, который является динамически исполняемым и очень модульным. Я имею дело с холстом. Я хочу, чтобы пользователь мог щелкнуть по, например, прямоугольнику, просмотреть его код и изменить, а затем загрузить/выполнить его. У меня есть ряд правил, но в основном у меня есть класс формы, и все, что определяет эту форму (цвет, прозрачность, заливки, штрихи...), должно передаваться как параметр объекту cosntructor, например:

rect = new Shape({color : 'rgba(0,0,0,1)' , 
  x : 0 , 
  y : 0 , 
  w : 100 , 
  h : 100 ,
  draw : function() {ctx.fillStyle = this.color;
    ctx.fillRect(this.x,this.y,this.w,this.h);
  }
});

Таким образом, код автоматически модульный, мне не нужно беспокоиться о том, что цвет определяется в верхней части страницы, а затем высота определяется наполовину вниз по странице и т.д. Теперь единственное, что мне нужно - это как-то передать в качестве параметра все строковое представление инициализации. Я мог бы обернуть его в функцию и вызвать toString, так вот

function wrapper(){
  rect = new Shape({color : 'rgba(0,0,0,1)' , 
        x : 0 , 
        y : 0 , 
        w : 100 , 
        h : 100 ,
        draw : function() {ctx.fillStyle = this.color;
          ctx.fillRect(this.x,this.y,this.w,this.h);
        },
        code : wrapper.toString()
      });
  }

но тогда есть две проблемы. 1) Мне нужно вручную удалить function wrapper() и trailing }, а также переместить каждую строку влево на одну вкладку. 2) нет гарантии, что пользователь не забудет включить функцию обертки, поскольку она абсолютно не нужна для целей рисования. Я пытаюсь думать о способе, которым обертка казалась бы естественной, но я не могу думать ни о чем. Но опять же я не спал более 30 часов.

Ответ 1

Я не могу поверить, что никто не предложил этого (я прошу прощения, если этот ответ находится где-то между строк). Я не думал об этом, потому что во время разработки все мои работы были клиентами. Все, что мне действительно нужно сделать, это загрузить код один раз Ajax как javascript. После его загрузки и создания объекта я загружаю его снова как строку и назначаю его переменной в объекте.

Ответ 2

ОК... Повторное рассмотрение... Я думаю, что вы хотите; -).

>>> function A() {this.name ="foo";}
undefined
>>> A.toString()
"function A() {this.name ="foo";}"

Ответ 3

Изменить: добавлена ​​довольно-печатная версия.

Вы можете JSON.stringify() аргумент конструктора, если он совместим с JSON. Вот функция toString(), которая основывается на этой идее, но со слегка обобщенной версией JSON.stringify(), которая принимает строковые функции:

function Shape(x){
    this.x = x;
}
Shape.prototype.toString = function() {
    function stringify(data, prefix) {
        function unicode_escape(c) {
            var s = c.charCodeAt(0).toString(16);
            while (s.length < 4) s = "0" + s;
            return "\\u" + s;
        }
        if (!prefix) prefix = "";
        switch (typeof data) {
            case "object":  // object, array or null
                if (data == null) return "null";
                var i, pieces = [], before, after;
                var indent = prefix + "    ";
                if (data instanceof Array) {
                    for (i = 0; i < data.length; i++)
                        pieces.push(stringify(data[i], indent));
                    before = "[\n";
                    after = "]";
                }
                else {
                    for (i in data)
                        pieces.push(i + ": " + stringify(data[i], indent));
                    before = "{\n";
                    after = "}";
                }
                return before + indent
                       + pieces.join(",\n" + indent)
                       + "\n" + prefix + after;
            case "string":
                data = data.replace(/\\/g, "\\\\").replace(/"/g, '\\"')
                           .replace(/\n/g, "\\n").replace(/\r/g, "\\r")
                           .replace(/\t/g, "\\t")
                           .replace(/[\x00-\x19]/g, unicode_escape);
                return '"' + data + '"';
            default:
                return String(data).replace(/\n/g, "\n" + prefix);
        }
    }
    return "new Shape(" + stringify(this.x) + ")";
};

var rect = new Shape({color : 'rgba(0,0,0,1)' , 
  x : 0 , 
  y : 0 , 
  w : 100 , 
  h : 100 ,
  draw : function() {ctx.fillStyle = this.color;
    ctx.fillRect(this.x,this.y,this.w,this.h);
  }
});
console.log(rect.toString());

Вывод:

new Shape({
    color: "rgba(0,0,0,1)",
    x: 0,
    y: 0,
    w: 100,
    h: 100,
    draw: function() {
        ctx.fillStyle = this.color;
        ctx.fillRect(this.x, this.y, this.w, this.h);
    }
})

Ответ 4

Вот еще одно решение, которое может работать (используя пример yankee). Однако я не уверен, что произойдет, если A уже существует? Возможно, вам нужно сделать "delete (A)"; перед сохранением в хранилище.

// Create A
// function A() {this.name = "foo";}

var x = 'function A() {this.name = "foo";}'; // Store function to variable using A.toString();

// Save x in storage

// -- Page reload --

// Load and eval x from storage
eval(x);

var a = new A(); // Use A
alert(a.name);

Ответ 5

function dumpObject(obj) 
{     
    var output = "";     
    for (var i in obj) 
    {         
        var msg = i + "= " + obj[i];         
        output += msg + "\n";     
    }     
    return output; 
} 

var myObject = {
    myName: 'Daniel',

    get_name: function()
    {
        return this.myName;
    }
}

alert( dumpObject(myObject) );
//this will output:
//
//    myName= Daniel
//    get_name=function()
//    {
//        return this.myName;
//    }

Вот моя скрипка для этого: http://jsfiddle.net/DanielDZC/vXrQf/

Ответ 6

Обратитесь к фрагменту кода ниже:

function A() {
  this.name = 'Kaiser Sauze';
}

a = new A();

console.log(a.constructor.toString());

// output
// "function A(){
//   this.name = 'Kaiser Sauze';
// }"

Ответ 8

Я бы не рекомендовал использовать на производственном сервере только для тестирования и отладки, но существует метод с именем toSource(), который возвращает источник функции как String:

function add(a, b) {
    return a + b;
}
console.log(add.toSource());

Выходы:

function add(a, b) { return a + b; }

Доступно в JS Fiddle: http://jsfiddle.net/IQAndreas/dP453/1/

Обратите внимание, что Mozilla пометила этот метод как нестандартный (который, если вы читаете данные, означает "Только работает в FireFox" ).