Вопрос по google-closure, javascript, google-closure-compiler – Как я могу предотвратить предупреждение «Свойство MyProp1 никогда не определяется в MyObject»?

13

У меня есть некоторый HTML, который содержит строку JSON. вна DOM готов обратный звонок, у меня есть что-то вроде этого:

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

Позже в моем коде я напишу что-то такое:

var SomeVar = MyObject.MyProp1;

И затем, когда я запускаю код через компилятор Google Closure, я получаю предупреждение

Свойство MyProp1 никогда не определяется в MyObject.

Как должен быть написан код, чтобы он не генерировал предупреждение?

Ваш Ответ

5   ответов
1

чтобы помещать содержимое JSON в объект #TheJsonString в виде HTML, вы должны поместить его на своей странице как настоящий JavaScript. Если сервер генерирует контент на странице, то нет причин, по которым серверу нужно генерировать HTML, который вы затем анализируете. Сервер может просто создать переменную javascript внутри тега script и поместить в нее фактическую структуру данных javascript.

JSON.parse() очень полезен для анализа ответов ajax, но это действительно не нужно, когда сервер может просто поместить готовый javascript прямо в сгенерированную страницу.

На самом деле есть 12 строк json, и литералы вставляются из кода главной страницы. Я не хочу, чтобы у моего файла .master был некрасивый оператор eval. И это не решило бы проблему компилятора, так как у меня нет операторов json; они оцениваются во время выполнения. frenchie
Но я использую компилятор Google, где я копирую и вставляю свой JavaScript и где я хочу удалить предупреждения (FYI, 837 предупреждений). Операторы json доступны только во время выполнения, поэтому, даже если я поместил операторы json как eval в файл aspx, у меня все равно появится предупреждение в компиляторе Google, потому что его нет при компиляции кода! Чем больше я думаю об этом, тем больше я думаю, что решение заключается в наследовании прототипа, где мне нужно создать объект и привести синтаксический анализ json или чего-то в этом роде. frenchie
@frenchie - я знаю, что вы помещаете их в div. Я спрашиваю, почему вы делаете это, когда вы можете просто поместить их непосредственно в переменную javascript. Нет причин размещать их в виде строки на вашей странице. Это также решило бы проблему закрытия Google, потому что они были бы определены в реальном javascript. jfriend00
@frenchie - я понятия не имею, что страшного в том, что сервер генерирует структуры данных javascript на странице, которую он обслуживает. Это делается все время. Никаких заявлений не требуется. Вы используете неортодоксальный метод размещения данных на своей странице. Ваша жизнь была бы намного проще, если бы вы использовали лучший способ размещения данных на странице, но вы, похоже, боретесь с этим понятием, и мы действительно не знаем, почему. jfriend00
Я помещаю строки json в литерал, чтобы в браузере они были внутри div. Asp.net frenchie
15

. Это можно сделать с помощью@type тег:

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

гдеMyProp1 это название имущества, иstring это тип.

Компилятор Google Closure переименует переменную. Если вы не хотите этого, вы должны использовать кавычки + скобки вместо точечной нотации:

MyObject['MyProp1']

пример: вставьте следующее вЗакрытие Компилятор:

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

Выход:

var a;a=JSON.parse(prompt(""));alert(a.a);
Хорошо, спасибо, теперь это работает! В целом, лучше ли использовать точечную нотацию по сравнению с скобочной нотацией или это просто вопрос стиля / предпочтения? Кроме того, я планирую использовать компилятор Google, а затем повторно скомпилировать скомпилированный код в jscrambler. Я знаю, что это не помешает реверс-инжинирингу, но я только жду времени. Будет ли работать двойная запутанность? frenchie
@frenchie Как правило, обозначение в скобках / точках является вопросом предпочтения. Однако в компиляторе Closure для сохранения имен необходимо использовать скобочные обозначения. Точечная нотация используется в скомпилированном выводе. И да, двойное запутывание действительно усложнит реверс-инжиниринг. Убедитесь, что вы тестировали производительность кода до / после запутывания. Rob W
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>

Проблема в том, что у меня нет строк json, когда я вставляю свой код в компилятор Google: json генерируется во время выполнения и отличается для каждого пользователя. Чем больше я думаю об этом, тем больше я думаю, что решение заключается в наследовании прототипа, где мне нужно создать объект и привести синтаксический анализ json, или что-то в этом роде. frenchie
7

вы можете использовать@suppress аннотация:

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

Чтобы отключить это предупреждениеглобально, использоватьjscomp_off флаг компилятора, чтобы отключитьmissingProperties класс предупреждений.

3

var SomeVar = MyObject['MyProp1'];

Похожие вопросы