(Điều này đã được thêm vào thư viện của tôi tại GitHub )
Phát minh lại bánh xe ở đây! Không có giải pháp nào trong số này làm việc cho tình huống của tôi. Vì vậy, tôi nhanh chóng ghi lại câu trả lời của wilsonpage . Cái này không phải để in ra màn hình (thông qua bảng điều khiển, hoặc trường văn bản hoặc bất cứ thứ gì). Nó hoạt động tốt trong những tình huống đó và hoạt động tốt như OP yêu cầu alert
. Nhiều câu trả lời ở đây không giải quyết bằng cách sử dụng alert
như OP yêu cầu. Dù sao đi nữa, tuy nhiên, nó được định dạng để truyền dữ liệu. Phiên bản này dường như trả về một kết quả rất giống như toSource()
. Tôi đã không được thử nghiệm JSON.stringify
, nhưng tôi cho rằng đây là điều tương tự. Phiên bản này giống như một poly-fil hơn để bạn có thể sử dụng nó trong bất kỳ môi trường nào. Kết quả của chức năng này là một khai báo đối tượng Javascript hợp lệ.
Tôi sẽ không nghi ngờ nếu một cái gì đó như thế này đã có trên SO ở đâu đó, nhưng nó chỉ ngắn hơn để làm nó hơn là dành một lúc để tìm kiếm câu trả lời trong quá khứ. Và vì câu hỏi này là câu hỏi hàng đầu của tôi trên google khi tôi bắt đầu tìm kiếm về điều này; Tôi nghĩ rằng đặt nó ở đây có thể giúp đỡ người khác.
Dù sao đi nữa, kết quả từ hàm này sẽ là một chuỗi đại diện cho đối tượng của bạn, ngay cả khi đối tượng của bạn có các đối tượng và mảng nhúng, và ngay cả khi các đối tượng hoặc mảng đó có thêm các đối tượng và mảng được nhúng. (Tôi nghe nói bạn thích uống? Vì vậy, tôi đã làm lạnh chiếc xe của bạn bằng một chiếc máy làm mát. Và sau đó, tôi đã làm lạnh chiếc máy làm mát của bạn bằng máy làm mát. Vì vậy, máy làm mát của bạn có thể uống, trong khi bạn mát mẻ.)
Mảng được lưu trữ []
thay vì {}
và do đó không có cặp khóa / giá trị, chỉ có giá trị. Giống như các mảng thông thường. Do đó, chúng được tạo như mảng làm.
Ngoài ra, tất cả các chuỗi (bao gồm cả tên khóa) được trích dẫn, điều này là không cần thiết trừ khi các chuỗi đó có các ký tự đặc biệt (như dấu cách hoặc dấu gạch chéo). Nhưng, tôi không cảm thấy như phát hiện ra điều này chỉ để xóa một số trích dẫn mà nếu không vẫn hoạt động tốt.
Chuỗi kết quả này sau đó có thể được sử dụng với eval
hoặc chỉ đưa nó vào một thao tác chuỗi var thru. Do đó, tạo lại đối tượng của bạn một lần nữa, từ văn bản.
function ObjToSource(o){
if (!o) return 'null';
var k="",na=typeof(o.length)=="undefined"?1:0,str="";
for(var p in o){
if (na) k = "'"+p+ "':";
if (typeof o[p] == "string") str += k + "'" + o[p]+"',";
else if (typeof o[p] == "object") str += k + ObjToSource(o[p])+",";
else str += k + o[p] + ",";
}
if (na) return "{"+str.slice(0,-1)+"}";
else return "["+str.slice(0,-1)+"]";
}
Hãy cho tôi biết nếu tôi làm hỏng tất cả, hoạt động tốt trong thử nghiệm của tôi. Ngoài ra, cách duy nhất tôi có thể nghĩ ra để phát hiện loại array
là kiểm tra sự hiện diện của length
. Bởi vì Javascript thực sự lưu trữ các mảng dưới dạng đối tượng, tôi thực sự không thể kiểm tra loại array
(không có loại nào như vậy!). Nếu bất cứ ai khác biết một cách tốt hơn, tôi rất thích nghe nó. Bởi vì, nếu đối tượng của bạn cũng có một thuộc tính được đặt tên length
thì hàm này sẽ coi nhầm nó là một mảng.
EDIT: Đã thêm kiểm tra cho các đối tượng có giá trị null. Cảm ơn Brock Adams
EDIT: Dưới đây là chức năng cố định để có thể in các đối tượng đệ quy vô hạn. Điều này không in giống như toSource
từ FF vì toSource
sẽ in đệ quy vô hạn một lần, trong đó, chức năng này sẽ giết nó ngay lập tức. Hàm này chạy chậm hơn hàm trên, vì vậy tôi sẽ thêm nó vào đây thay vì chỉnh sửa hàm trên, vì nó chỉ cần thiết nếu bạn định chuyển các đối tượng liên kết lại với chính chúng, ở đâu đó.
const ObjToSource=(o)=> {
if (!o) return null;
let str="",na=0,k,p;
if (typeof(o) == "object") {
if (!ObjToSource.check) ObjToSource.check = new Array();
for (k=ObjToSource.check.length;na<k;na++) if (ObjToSource.check[na]==o) return '{}';
ObjToSource.check.push(o);
}
k="",na=typeof(o.length)=="undefined"?1:0;
for(p in o){
if (na) k = "'"+p+"':";
if (typeof o[p] == "string") str += k+"'"+o[p]+"',";
else if (typeof o[p] == "object") str += k+ObjToSource(o[p])+",";
else str += k+o[p]+",";
}
if (typeof(o) == "object") ObjToSource.check.pop();
if (na) return "{"+str.slice(0,-1)+"}";
else return "["+str.slice(0,-1)+"]";
}
Kiểm tra:
var test1 = new Object();
test1.foo = 1;
test1.bar = 2;
var testobject = new Object();
testobject.run = 1;
testobject.fast = null;
testobject.loop = testobject;
testobject.dup = test1;
console.log(ObjToSource(testobject));
console.log(testobject.toSource());
Kết quả:
{'run':1,'fast':null,'loop':{},'dup':{'foo':1,'bar':2}}
({run:1, fast:null, loop:{run:1, fast:null, loop:{}, dup:{foo:1, bar:2}}, dup:{foo:1, bar:2}})
LƯU Ý: Cố gắng in document.body
là một ví dụ khủng khiếp. Đối với một, FF chỉ in một chuỗi đối tượng trống khi sử dụng toSource
. Và khi sử dụng chức năng trên, FF gặp sự cố SecurityError: The operation is insecure.
. Và Chrome sẽ sụp đổ Uncaught RangeError: Maximum call stack size exceeded
. Rõ ràng, document.body
không có nghĩa là được chuyển đổi thành chuỗi. Bởi vì nó quá lớn hoặc chống lại chính sách bảo mật để truy cập vào một số thuộc tính nhất định. Trừ khi, tôi đã làm hỏng một cái gì đó ở đây, hãy nói!