2011-07-05 29 views
11

Trước hết, tôi xin lỗi nếu đây là một bản sao, nhưng mỗi lần tôi googled cho 'đối tượng' và 'mã' tôi có các trang hướng dẫn.Đối tượng Javascript nhận được mã như chuỗi

Tôi muốn biết liệu có cách nào dễ dàng để lấy mã được liên kết với một đối tượng hay không. Một cái gì đó như

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

Tôi muốn có thể xem mã, sửa đổi và tải lại chức năng, tất cả từ bên trong trình duyệt. Tôi muốn biết nếu có một số cách để làm điều này, hoặc nếu tôi phải thủ bơm bằng cách làm một cái gì đó như thế này:

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

sau đó mỗi khi tải sử dụng lên soạn thảo văn bản để xem this.code tôi kết nối thay đổi để cập nhật this.code.

EDIT

quay ra yankee đề nghị một giải pháp đơn giản để này

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

nhưng trong việc thực hiện của tôi biến 'x' có thể là một chức năng (thực sự là một đối tượng phức tạp với các biến, chức năng và các đối tượng phụ mà tôi kết hợp thông qua một cuộc gọi đến dojo.mixin), vì vậy điều tôi thực sự muốn là biết mã khi được tạo ra, giống như vậy

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*/);" 

nhưng, của bạn đã biết, tất cả những gì được sản xuất là một cái gì đó giống như "Object". Tôi đã gần như tìm thấy một khoảng cách này, bằng cách đặt khởi tạo trong một chức năng như vậy

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*/); 
}" 

nhưng đó là khó hiểu, và sau đó tôi phải đi vào và bắt đầu phân tích các chuỗi mà tôi không muốn làm.

EDIT: Lý do tôi yêu cầu tất cả điều này là b/c Tôi muốn tạo mã có thể thực thi động và mô đun cao. Tôi đang xử lý canvas. Tôi muốn người dùng có thể nhấp vào một, ví dụ, hình chữ nhật, xem mã của nó, và sửa đổi và sau đó tải/thực hiện nó. Tôi có một loạt quy tắc nhưng về cơ bản tôi có một lớp hình dạng và mọi thứ xác định hình dạng đó (màu sắc, độ trong suốt, đầy, nét ...) phải được chuyển thành tham số đối tượng cosntructor, như sau:

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); 
    } 
}); 

Bằng cách này mã được tự động mô-đun, tôi không phải lo lắng về màu sắc được xác định ở đầu trang và sau đó chiều cao được xác định một nửa xuống dưới trang, v.v. Bây giờ điều duy nhất tôi cần là bằng cách nào đó, vượt qua như một tham số, toàn bộ chuỗi đại diện trên của khởi tạo. Tôi có thể bọc nó trong một chức năng và gọi toString trên đó, như vậy

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() 
     }); 
    } 

nhưng sau đó có hai vấn đề. 1) Tôi phải tự xóa function wrapper() và theo sau } cũng như di chuyển mọi dòng sang bên trái bằng một tab. 2) không đảm bảo rằng người dùng sẽ nhớ bao gồm chức năng trình bao bọc vì nó hoàn toàn không cần thiết cho các mục đích vẽ. Tôi đang cố gắng nghĩ ra một cách mà trình bao bọc có vẻ tự nhiên, nhưng tôi không thể nghĩ ra được. Nhưng sau đó một lần nữa tôi đã không ngủ trong hơn 30 giờ.

+1

+1 chỉ để tham chiếu Kaiser Sauze ...mặc dù tôi nghĩ rằng nó được đánh vần Keyser Söze ;-) –

+0

@ Jason: Tôi không bao giờ có thể nhớ làm thế nào để đánh vần nó, vì vậy khi tôi đưa ra số của tôi cho phụ nữ, tôi đi bởi Rolo Tomasi ;-) – puk

Trả lời

1

Tôi không thể tin rằng không ai đề xuất điều này (tôi xin lỗi nếu câu trả lời này nằm ở đâu đó giữa các dòng). Tôi không nghĩ về nó bởi vì tại thời điểm phát triển, tất cả công việc của tôi là khách hàng. Tất cả những gì tôi thực sự phải làm là tải mã một lần với Ajax là javascript. Khi nó được nạp và một đối tượng được tạo, tôi tải nó lại như một chuỗi và gán nó cho một biến trong đối tượng.

17

OK ... Xem xét lại ... Tôi nghĩ đó là những gì bạn muốn ;-).

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

Wow đó là thực sự siêu mát mẻ . Tôi thường slam Javascript cho là hoàn toàn kém hơn Python, nhưng trong trường hợp này, nó thắng. Thật không may nó không phải là những gì tôi muốn. Bây giờ tôi nhận ra rằng đó là một câu hỏi ngu ngốc b/c đối tượng không có biểu diễn chuỗi. Tôi sẽ hoặc reimplement tất cả mọi thứ như là một lớp học hoặc tìm một cách khác để làm điều đó. Cảm ơn mặc dù. – puk

+0

cũng tôi chỉ có thể đặt khởi tạo đối tượng bên trong một hàm và sau đó gọi đến chuỗi trên đó. – puk

+0

Tôi đoán tôi sẽ chỉnh sửa câu hỏi để cập nhật tất cả những người quan tâm. Ngoài ra, vì một số lý do, khi tôi làm AT yankee nó không xuất hiện. – puk

1
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; 
// } 

Đây là fiddle tôi cho rằng: http://jsfiddle.net/DanielDZC/vXrQf/

+0

Tôi không nghĩ rằng đó là những gì tôi đang tìm kiếm, tôi muốn mã như nó được, không chỉ là tài sản. – puk

+0

Điều đó sẽ hiển thị các chức năng, thuộc tính, vv nhưng mỗi một trong số chúng một cách riêng biệt. bạn có thể điều chỉnh nó để mỗi vòng lặp thêm công cụ vào một chuỗi thay vì cảnh báo nó. trong thực tế, hãy để tôi thay đổi nó ... –

+0

Daniel, cảm ơn bạn vì jsfiddle. Nó chắc chắn xóa mọi thứ :) – puk

3

Sửa: thêm khá-in.

Bạn có thể JSON.stringify() đối số của hàm tạo, nếu nó tương thích với JSON. Đây là một chức năng toString() đó được xây dựng trên ý tưởng này, nhưng với một phiên bản hơi tổng quát của JSON.stringify() chấp nhận chức năng stringifying:

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()); 

Đầu ra là:

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); 
    } 
}) 
+0

wow Tôi không mong đợi nhiều câu trả lời này. Có lẽ tôi nên giải thích tại sao tôi hỏi câu hỏi này ngay từ đầu. Tôi sẽ chỉnh sửa lại. – puk

+0

Tôi đã chỉnh sửa lại câu hỏi của mình. Tôi giải thích tại sao tôi cần nó, và tại sao tôi không cần cấu trúc của đối tượng, mà là cấu trúc của chính mã đó. Vì vậy, tôi cần, vì lý do thẩm mỹ, các tab, dấu cách và ký tự dòng mới. Nếu không, người dùng sẽ gõ một cái gì đó, lưu nó, và sau đó khi họ mở lại nó, tất cả của một đột ngột tất cả các mã đã được san bằng một dòng duy nhất – puk

+0

Không có cách nào bạn có thể phục hồi không gian ban đầu, tab và newlines, trừ khi mã được lưu dưới dạng chuỗi ở vị trí đầu tiên (có thể thực sự là con đường dễ nhất để theo dõi). Tôi đã chỉnh sửa câu trả lời của mình để cải thiện tính thẩm mỹ của đầu ra. Tuy nhiên, 'toString()' này thực sự lại thụt lề với kiểu thụt lề của tôi (bốn dấu cách không gian, không có dấu cách trước ':' ...), mặc dù mã ban đầu được nhập bằng kiểu của bạn. Bạn rõ ràng có thể chỉnh sửa 'toString()' để phù hợp với phong cách của bạn. –

0

Âm thanh như bạn đang tìm kiếm Reflection và/hoặc hỗ trợ Introspection. Tôi không chắc chắn nơi các động cơ chính khác đang ở trong này liên quan nhưng SpiderMonkey của Parser API gần đây đã được tham chiếu trong một bài viết trên Extension Introspection with Chrome Privileges.

+0

Tôi tránh xa việc sử dụng các trình phân tích cú pháp vì tôi có ít hoặc không có kinh nghiệm với chúng, nhưng tôi có thể phải bắt đầu. Một điều nữa tôi nghĩ là lưu trữ mọi chức năng dưới dạng tệp rồi tải chúng trong index.html (hoặc để hợp nhất hiệu quả chúng thành tệp .js duy nhất bất cứ khi nào một trong các tệp phụ bị thay đổi và chỉ tải trong index.html), sau đó có mỗi đối tượng được tạo ra bởi tập tin đó được nhận thức của đường dẫn tập tin. – puk

+0

có lý do nào khiến các dấu hiệu AT (@) của tôi không hiển thị không? Tôi không còn có thể trả lời người dùng cụ thể dưới dạng @ user (@user). Cú pháp đã thay đổi hay tôi đã vô tình thay đổi cài đặt của tôi? Ví dụ tôi đã cố gắng bắt đầu bình luận trước đó của tôi với '@ psema4' nhưng tôi không thấy nó ở đó – puk

+0

cảm ơn cho liên kết psema4. Tôi sẽ sử dụng điều này cho các phần không đối tượng (ví dụ: các lớp và toàn bộ tập lệnh) – puk

2

Đây là một giải pháp khác có thể hoạt động (sử dụng ví dụ của yankee). Tuy nhiên tôi không chắc chắn những gì sẽ xảy ra nếu A đã tồn tại? Có lẽ bạn nên làm một "xóa (A);" trước khi lưu nó vào bộ nhớ.

// 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); 
0

tôi sẽ không khuyên bạn sử dụng trên một máy chủ sản xuất, chỉ để thử nghiệm và gỡ lỗi, nhưng there is a method named toSource() mà trả về nguồn gốc của một chức năng như một String:

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

Đầu ra:

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

Có sẵn trên JS Fiddle: http://jsfiddle.net/IQAndreas/dP453/1/

Lưu ý t mũ Mozilla đã đánh dấu phương thức này là phi tiêu chuẩn (nếu bạn read the details có nghĩa là "Chỉ hoạt động trong FireFox").

1

Tham khảo đoạn mã dưới đây:

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

 
a = new A(); 
 

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

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

Khi bạn làm new A(), function A trở thành các nhà xây dựng của đối tượng a. Do đó, bạn có thể tham khảo function A qua thuộc tính constructor của đối tượng a.

Read more about Javascript constructor on MDN.

Các vấn đề liên quan