2012-03-05 39 views
12

Tôi có một số HTML có chứa một chuỗi JSON. Trong trên DOM sẵn sàng gọi lại, tôi có một cái gì đó như thế này:Làm cách nào để ngăn chặn cảnh báo 'Thuộc tính MyProp1 không bao giờ được xác định trên MyObject'?

MyObject = JSON.parse($('#TheJsonString').html()); 

Sau đó trong mã của tôi, tôi viết một cái gì đó này:

var SomeVar = MyObject.MyProp1; 

Và sau đó khi tôi chạy mã thông qua việc đóng cửa Google trình biên dịch, tôi nhận được cảnh báo

Thuộc tính MyProp1 không bao giờ được xác định trên MyObject.

Mã nên được viết sao cho mã không tạo cảnh báo?

Trả lời

14

Cách sạch để loại bỏ các cảnh báo là bằng cách xác định cấu trúc của JSON. Điều này có thể được thực hiện bằng cách sử dụng thẻ @type:

/** @type {{MyProp1:string}} */ 

đâu MyProp1 là tên của tài sản, và string là loại.

Trình biên dịch đóng cửa của Google sẽ đổi tên biến. Nếu bạn không muốn điều đó, bạn phải sử dụng dấu ngoặc kép + ngoặc thay vì bong bóng dot-ký hiệu:

MyObject['MyProp1'] 

Ví dụ: dán sau trong Closure Compiler:

// ==ClosureCompiler== 
// @compilation_level ADVANCED_OPTIMIZATIONS 
// ==/ClosureCompiler== 

var MyObject; 
function x() { // Magic happens at the next line 
    /** @type {{MyProp1:string}}*/ 
    MyObject = JSON.parse(prompt('')); 
} 
function afterX() { 
    var SomeVar = MyObject.MyProp1; 
    alert(SomeVar); 
} 
x(); 
afterX(); 

Output:

var a;a=JSON.parse(prompt(""));alert(a.a); 
+0

Ok cảm ơn, bây giờ nó hoạt động! Nói chung, có phải "tốt hơn" để sử dụng ký hiệu chấm và ký hiệu khung hoặc chỉ là vấn đề về phong cách/sở thích? Ngoài ra, tôi có kế hoạch sử dụng trình biên dịch google và sau đó reobfuscate mã biên dịch trong jscrambler. Tôi biết điều này sẽ không ngăn cản kỹ thuật đảo ngược nhưng tôi chỉ tìm cách để mua thời gian. Sẽ làm tăng gấp đôi obfuscation? – frenchie

+1

@frenchie Nói chung, ký hiệu dấu ngoặc/chấm là một vấn đề ưu tiên. Tuy nhiên, trong trình biên dịch đóng cửa, ký hiệu khung phải được sử dụng, để bảo toàn tên. Dấu chấm được sử dụng trong đầu ra được biên dịch. Và có, đôi obfuscation thực sự sẽ làm cho kỹ thuật đảo ngược khó hơn. Hãy chắc chắn rằng bạn kiểm tra hiệu suất của mã trước/sau khi obfuscation. –

1

Thay vì đặt nội dung JSON trong đối tượng #TheJsonString dưới dạng HTML, bạn nên đặt nó trong trang của mình dưới dạng javascript thực tế. Nếu máy chủ đang tạo nội dung trong trang, thì không có lý do gì mà máy chủ cần tạo HTML mà sau đó bạn phân tích cú pháp. Máy chủ chỉ có thể tạo biến javascript bên trong thẻ tập lệnh và đặt cấu trúc dữ liệu javascript thực tế vào đó.

JSON.parse() rất hữu ích để phân tích phản hồi ajax, nhưng thực sự không cần thiết khi máy chủ chỉ có thể đặt javascript đã hoàn thành ngay trong trang được tạo ở nơi đầu tiên.

+0

Tôi đang đặt các chuỗi json theo nghĩa đen, vì vậy trong trình duyệt, chúng nằm trong div. Asp.net – frenchie

+0

@frenchie - Tôi biết bạn đang đặt chúng vào một div. Tôi hỏi lý do tại sao bạn đang làm điều đó khi bạn chỉ có thể đặt chúng trực tiếp vào một biến javascript. Không có lý do gì để đưa chúng vào dạng chuỗi trong trang của bạn. Điều này cũng sẽ giải quyết vấn đề đóng cửa của Google vì chúng sẽ được xác định bằng javascript thực. – jfriend00

+1

Thực tế có 12 chuỗi json và các chữ được chèn từ mã trang chính đằng sau. Tôi không muốn tệp .master của tôi có một câu lệnh eval máy chủ xấu xí. Và điều đó sẽ không giải quyết vấn đề trình biên dịch anyway vì tôi không có các câu lệnh json; chúng được đánh giá khi chạy. – frenchie

0
<!DOCTYPE html> 
<html> 
<head></head> 
<body> 
<div id="TheJsonString"> 
    {"bindings": "hr", "method":"asd"} 
</div> 
<script type="text/javascript" src="jquery-1.7.1.min.js"></script> 
<script type="text/javascript"> 
    var MyObject = JSON.parse($('#TheJsonString').html()); 

    var SomeVar = MyObject.bindings; 

    console.log(SomeVar); 
</script> 
</body> 
</html> 

Tôi đã thử nghiệm nó như thế này, nhưng nó hoạt động tốt mà không có bất kỳ cảnh báo nào.

+0

Vấn đề là tôi không có chuỗi json khi tôi dán mã của tôi trong trình biên dịch google: json được tạo khi chạy và khác nhau đối với mọi người dùng. Tôi càng nghĩ về nó, tôi càng nghĩ rằng giải pháp là trong sự thừa kế nguyên mẫu, nơi tôi cần tạo một đối tượng và phân tích cú pháp của json, hoặc một cái gì đó tương tự. – frenchie

3

Hãy thử truy cập thuộc tính theo cách này:

var SomeVar = MyObject['MyProp1']; 
7

Để chặn cảnh báo này cho một chức năng cụ thể, bạn có thể sử dụng chú thích @suppress:

/** 
* @suppress {missingProperties} 
*/ 
function useJsonObject() { ... } 

Để tắt cảnh báo này toàn cầu, sử dụng cờ jscomp_off trình biên dịch để tắt missingPropertiesclass of warnings.

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