2016-01-05 2 views
3

У меня есть следующий фрагмент, в котором последнее использование «удалить» возвращает неожиданное значение.Неожиданное значение «удалить»

function Shape() { 
 
    this.a = 10; 
 
} 
 
Shape.prototype.a = 20; 
 
var s = new Shape(); 
 
console.log(s.a); // 10 
 
delete s.a; //true 
 
console.log(s.a) // 20 
 
delete s.a; //true 
 
console.log(s.a); // 20

Даже если окончательное «удалить са» возвращает истину, значение «са» по-прежнему возвращает 20.

Если мы не можем удалить объекты на прототипе с помощью ссылки из object (в этом случае 's'), почему ключевое слово delete возвращает true?

Во-вторых,

delete Shape.prototype.a; // true

выдает истинное и свойство действительно удаляется из Shape.prototype. Но есть ли способ удалить 'Shape.prototype.a' через ссылку на объект ''?

+1

Что вы имеете в виду '' delete' возвращает true'? 'delete' - это выражение, а не выражение. – thefourtheye

+0

Вы можете проверить возвращаемое значение «delete» в консоли. Он возвращает «true» после оценки инструкции, если элемент удален. –

+0

Пожалуйста, проверьте использование 'delete' перед тем, как опросить вопрос. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete –

ответ

3

Значение возвращаемого значения ключевого слова не указывает, действительно ли операция удаления действительно удалила поле. Из MDN article about delete keyword:

Возвращаемого значения

Бросков в строгом режиме, если свойство является собственным неперестраиваемым свойством (возвращает ложь в нестрогом). Возвращает true во всех других случаях .

В вашем случае s.a не является собственностью, поэтому delete всегда будет возвращать true. Не имеет значения, найдено ли свойство в цепочке прототипов или нет. Например:

delete {}.xyz; // also returns `true`. 

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

function deepDelete(o,key) { 
    while (o) { 
    delete o[key]; 
    o = Object.getPrototypeOf(o); 
    } 
} 

Пример:

function S(){} 
S.prototype.a = 8; 
var s = new S(); 
s.a = 9; 
console.log(s.a); // 9 
delete s.a; 
console.log(s.a); // 8 
deepDelete(s, 'a'); 
console.log(s.a); // undefined 
+0

Мне интересно, что делает 'deepDelete' для объектов хоста (скажем, элементов DOM в старом IE) ... ;-) –

+0

@JanDvorak Ну, честно говоря, я понятия не имею (кто? :)) –

+0

My Лучше всего предположить, что он выдает код. Либо с исключением с нулевым указателем, либо с чем-то странным и неустойчивым. –

1

function Shape() { 
 
    //this.a = 10; 
 
} 
 

 
Shape.prototype.a = 20; 
 
var s = new Shape(); 
 

 
console.log(s.a); 
 

 
delete Shape.prototype.a; 
 
console.log(s.a);

И, как цитирует MDN, а также упоминается в ответе by hege_hegedus,

Возвращаемое значение

Броски в строгом режиме, если свойство является собственным неперестраиваемый свойство (возвращает ложь в нестрогие). Возвращает true во всех других случаях .

Нижняя линия удалить это оператор, а не метод, и он просто удаляет свойство из объекта, a является собственностью Shape.prototype, а не объекта класса Shape, так что вам нужно удалить, что вместо от delete s.a

0

метод 'delete' может удалить только собственное свойство объекта, а не свойство прототипа. когда вы удаляете свойство, которое не exsit в объекте, оно возвращает ture; Однако ситуация ниже будет возвращать ложь:

delete Object.prototype; //renturn false; property can't set 
 
var x=1; 
 
delete this.x; //return flase;can not delete a global var 
 
function f(){} 
 
delete this.f; //return false; can not delete a global function

+0

вы также можете использовать оператор 'in', hasOwnProperty() или propertyIsEnumerable(), чтобы проверить, принадлежит ли свойство объекту. и есть еще простой способ сделать это: o.x! == undefined; – Jaycee

Смежные вопросы