Як уникнути змінної "ініціалізації" при посилання на батьківський об'єкт JavaScript?

Я знаю, що є багато питань "як уникнути цього попередження", але, схоже, що моє перше специфічне для JavaScript. У цьому випадку я хочу вказати те, що я ініціюю у власній декларації, наприклад:

var foo = new Foo({
  bar: new Bar({
    x: function(){
      doStuff(foo);
    }
  });
});

(Якщо це виглядає знайомо, можливо, ви раніше використовували ExtJS - ось так складається більшість їх матеріалів.)

Коли я називаю foo.bar.x() , я хочу повернутись до Foo ( foo ), яким належить панель ( bar ) це викликає функцію ( x ). Це працює, але мій Eclipse попереджає мене, що "foo може не бути ініціалізованим", посилання на виклик doStuff (); - оскільки, коли двигун спочатку бачить лінію, ми не закінчили визначення foo ще не визначено. Звичайно, x() не можна викликати, якщо не було успішно побудовано foo , але перевірка стилю, мабуть, не зрозуміла цього.

Тому я втрачаю з того, як боротися з цим. Чи слід ігнорувати попередження? Чи є спосіб позначити його як такий, так що я більше не отримую попередження? Я роблю це неправильно? Чи повинен я передавати посилання на інший спосіб?

5
Не використовуйте затемнення. Існують кращі інтегровані середовища (WebStorm 3)
додано Автор Raynos, джерело
Добре ловити, вибачте
додано Автор Coderer, джерело
Це помилка? Чи має бути doStuff (foo) замість doStuff (f)
додано Автор Duncan Smart, джерело

4 Відповіді

var Foo = function() { }

var Bar = function (obj) {
 //foo is not initialized
  obj.x();
 //called doStuff with undefined
}

var foo = new Foo({
  bar: new Bar({
    x: function(){
      doStuff(foo);
    }
  });
});

Eclipse правильно. Знову ж таки, якщо вам потрібна краща система аналізу, розгляньте можливість використання WebStorm 3.0 або Visual Studio 11 як JS IDE.

2
додано
@ Кодерер Приклад . Створіть об'єкти, а потім створіть зв'язок між об'єктами пізніше за допомогою належним чином називаного методу зв'язку.
додано Автор Raynos, джерело
@ Кодерер дивись на ваш код, панель залежить від Foo і Foo залежить від панелі. Целярні залежності, як це завжди, є злом.
додано Автор Raynos, джерело
@ Кодерер, який його називають, не вказує себе у своїй декларації. Це погана практика, щоб це зробити (якщо це просто декларація, як функція)
додано Автор Raynos, джерело
@Coderer Я просто показав вам контекст, в якому x викликається, коли foo не визначено
додано Автор Raynos, джерело
Тому я погоджуюсь з настроєм, але це для користувача інтерфейсу. Замініть "Foo" на "Dialog" та "Bar" за допомогою кнопки "Button" - у діалоговому вікні є кнопка, і коли я натискаю кнопку, вона повинна "робити речі" з батьківського діалогу. Чи є кращий дизайн для цього?
додано Автор Coderer, джерело
Добре знати - чи існує "правильний" спосіб сказати "дати мені посилання на об'єкт, який мені належить", як і в обставині, що я описую в ОП?
додано Автор Coderer, джерело
Гаразд, я все ще достатньо новим у JavaScript, що мені довелося перечитати чимсь десяток разів до натискання. Ви кажете, що якщо конструктор Bar називає свій метод x під час побудови (!!!), що метод намагатиметься використовувати foo , що не визначено. З цілком має сенс зараз. Чи є шаблон для запобігання цьому? Я не можу думати про одного.
додано Автор Coderer, джерело
вбік: VS не є варіантом (хоча я, як правило, шанувальник ...), оскільки я розробляю Linux. Я візьму серйозний погляд на WebStorm - дякую за покажчик!
додано Автор Coderer, джерело
Я розумію, чому це скаржаться. Я лише 99% впевнений, що не існує контексту виконання фактичного , в якому x() може бути викликаний , а foo залишається невизначеною. Так, конструктор Bar завершить роботу, перш ніж конструктор Foo завершить, але це не так, ніби щось може діяти на панелі об'єкт, який створений (і призначений для foo.bar ), доки не буде повністю збудовано об'єкт Foo , а тоді змінна foo ініціалізовано Якщо це має сенс ...
додано Автор Coderer, джерело

Це не має нічого спільного з JavaScript, але, можливо, щось пов'язано з Eclipse. Змінна foo може бути оголошена в будь-якому місці, оскільки декларації змінних обробляються до виконання будь-якого коду. Він також може бути ініціалізований у будь-який час до виклику doStuff (хоча ініціалізація змінних без оголошення їх вважається поганою).

1
додано

По-перше, побудовано Foo. Його конструктору передано нову панель, яка передана функцією за допомогою змінної foo.

Але для функції foo призначається лише значення після того, як конструктор Foo закінчив. У той момент функція вже оголошена, використовуючи незадекларовану змінну foo. Якщо ця функція використовується в конструкторі будь-якого рядка або Foo, вона не зможе.

0
додано
По-перше, foo створюється як властивість локальної змінної об'єкта. Код, здається, знаходиться в глобальному масштабі, тому він є властивістю глобального об'єкта (глобальної змінної) перед виконанням будь-якого коду. Коли викликається doStuff , foo існує, але може бути не призначено значення (тобто він може бути невизначеним).
додано Автор RobG, джерело
Я не пропоную це, я роз'яснюю, як це можливо, що змінну не призначено на даний момент, коли викликається doStuff. Я не кажу, що це, але це можливо, тому попередження видається. Чи foo оголошується як властивість або як глобальний, насправді не має значення в цій ситуації. Найпростіший спосіб запобігти попередженню - призначити значення (може бути нульовим) до foo перед тим, як викликати це призначення.
додано Автор GolezTrol, джерело
Ви пропонуєте, що код OP викине помилку? Бо це не буде.
додано Автор nrabinowitz, джерело

Я думаю, @RobG правильно, що це проблема Eclipse, і це, мабуть, краще всього лише для того, щоб мати справу з нею. Але якщо ви хочете уникнути цього, ви можете оголосити foo , перш ніж ініціалізувати його, і я впевнений, що це дозволить Eclipse скаржитися:

var foo;
foo = new Foo({
  bar: new Bar({
    x: function(){
      doStuff(foo);
    }
  });
});
0
додано
Я маю намір спробувати JSLint, але це настільки привабливим, що це займе час, щоб виправити всі його попередження, тому спочатку я мав намагатися працювати з "м'якими" попередженнями в Eclipse. Я знаю, що ці значення не мають ініціалізувати , але є значення, яке робить вас думкою про те, що може статися неправильно (наприклад, якщо ініціалізація коду усередині)
додано Автор Coderer, джерело
Просто оголошуючи це не досить добре (це оголошено, але все ще не технічно "ініціалізовано"), і мені важко змусити себе зробити щось подібне до var foo = "some marbage"; foo = новий Foo (....);
додано Автор Coderer, джерело
Javascript не вимагає присвоєння змінних значення (ініціалізоване), так що просто Eclipse є примарним. Запустіть код через jslint і подивіться, що ви отримуєте!
додано Автор RobG, джерело
Так, ви можете ініціалізувати його на null , але в той момент ви загвинчуєте свій стиль кодування відповідно до вашої IDE, що ні до чого.
додано Автор nrabinowitz, джерело
ІТ КПІ - JavaScript
ІТ КПІ - JavaScript
504 учасників

співтовариство javascript розробників в Telegram