Зачем объявлять свойства в прототипе для переменных экземпляра в JavaScript

Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException вообще.

См. также: A хороший список лучших практик

Я бы добавил, очень важно, хорошо использовать модификатор final. Использование "окончательной" модификатор, когда это применимо в Java

Сводка:

  1. Используйте модификатор final для обеспечения хорошей инициализации.
  2. Избегайте возврата null в методы, например, при возврате пустых коллекций.
  3. Использовать аннотации @NotNull и @Nullable
  4. Быстрое завершение работы и использование утверждений, чтобы избежать распространения нулевых объектов через все приложение, когда они не должен быть пустым.
  5. Сначала используйте значения с известным объектом: if("knownObject".equals(unknownObject)
  6. Предпочитают valueOf() поверх toString ().
  7. Используйте null safe StringUtils StringUtils.isEmpty(null).

25
задан iammilind 25 September 2018 в 11:57
поделиться

2 ответа

Значение в прототипе имеет поведение ключа, которое отличается от свойства, установленного непосредственно в экземпляре. Попробуйте это:

// Create a constructor
function A() {}

// Add a prototype property
A.prototype.name = "Freddy";

// Create two object instances from
// the constructor
var a = new A();
var b = new A();

// Both instances have the property
// that we created on the prototype
console.log(a.name); // Freddy
console.log(b.name); // Freddy

// Now change the property on the
// prototype
A.prototype.name = "George";

// Both instances inherit the change.
// Really they are just reading the
// same property from the prototype
// rather than their own property
console.log(a.name); // George
console.log(b.name); // George

Это было бы невозможно без прототипного наследования.

Вы можете проверить, является ли свойство свойством экземпляров или свойством прототипа, используя метод hasOwnProperty.

console.log(a.hasOwnProperty("name")); // false

Экземпляр может переопределить значение prototype.

b.name = "Chris";
console.log(b.hasOwnProperty("name")); // true
console.log(a.name); // George
console.log(b.name); // Chris

И вернитесь к значению prototype.

delete b.name;
console.log(b.hasOwnProperty("name")); // false
console.log(b.name); // George

Это мощная часть прототипического наследования.

В другом шаблоне:

function A() {
  this.name = "George";
}

Переменная this.name объявляется снова с каждым новым экземпляром.

Имеет смысл иметь методы как функции, объявленные в прототипе. Вместо того, чтобы определение функции повторно объявлялось в каждом экземпляре, все экземпляры могут совместно использовать одну функцию.

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

Код в скрипке

55
ответ дан Stuart Wakefield 25 September 2018 в 11:57
поделиться

Да, я согласен, что прототип можно использовать для значений свойств (переменных) по умолчанию. Функция конструктора не должна объявлять свойство; это может быть сделано условно.

function Person( name, age ) {
    this.name = name;

    if ( age ) {
        this.age = age;
    }
}

Person.prototype.sayHello = function() {
    console.log( 'My name is ' + this.name + '.' );
};

Person.prototype.sayAge = function() {
    if ( this.age ) {
        console.log( 'I am ' + this.age + ' yrs old!' ); 
    } else {
        console.log( 'I do not know my age!' );
    }
};

Person.prototype.age = 0.7;

//-----------

var person = new Person( 'Lucy' );
console.log( 'person.name', person.name ); // Lucy
console.log( 'person.age', person.age );   // 0.7
person.sayAge();                           // I am 0.7 yrs old!

Посмотрите, как Люси age условно объявлен и инициализирован.

0
ответ дан Michael R 25 September 2018 в 11:57
поделиться
Другие вопросы по тегам:

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