2015-02-08 8 views
0

Недавно я начал использовать traceur и наткнулся на странное поведение при создании класса со значениями по умолчанию на прототипе. Я хочу знать, является ли это ошибкой в ​​traceur или это предназначенное поведение для классов ES6?es6 класс с свойством по умолчанию на прототипе броска в traceur

class hasDefault { 
    setValue (v) { 
    this.v = v; 
    } 
} 
Object.defineProperty(hasDefault.prototype, "v", { 
    value : 5, 
    enumerable : true 
}); 

let a = new hasDefault; 
console.assert(a.v === 5); 
a.setValue(2); 
console.assert(a.v === 2); 

run in traceur REPL

Он выдает ошибку, что я не могу назначить для чтения свойства только «против», когда я пытаюсь установить его. Что не имеет смысла, поскольку свойство определено на прототипе, а не в экземпляре. Также я не могу получить эту ошибку, чтобы выбросить es5 на запечатанных/замороженных/не расширяемых объектах, и насколько я знаю, Proxies не реализованы в V8, поэтому ... как это порождает ошибку в первую очередь ? Это не ошибка времени компиляции.

Мой главный интерес - не «заставить его работать», что тривиально. Все, что вам нужно сделать, это заменить this.v = v эквивалентом Object.defineProperty. Я прежде всего хочу знать, если и почему он ведет себя таким образом, и если в этой структуре данных есть негативные последствия для производительности, которые перевешивают прирост памяти, назначая свойства по умолчанию прототипу вместо хранения их на каждом экземпляре.

ответ

1

Он выдает ошибку, что я не могу назначить для чтения свойства только «против», когда я пытаюсь установить его. Что не имеет смысла, поскольку свойство определено на прототипе, а не в экземпляре.

Да, это свойство только для чтения, как атрибут writable дефолта в false. И когда свойство v наследуется, этот атрибут также действует для присвоений.

Кроме того, я не смог получить эту ошибку, чтобы бросить в ES5

Вы просто должны использовать строгий режим, и он будет делать:

"use strict"; 
var test = Object.create(Object.defineProperty({}, "v", {value: 5, enumerable: true})); 
console.log(test.v) // 5 
test.v = 1; // Unhandled Error: Invalid assignment in strict mode 
+0

ah ok thanks Я не знал, что дескрипторы свойств работают так, как они унаследованы, но это имеет смысл. Вы также правы в строгом режиме, который был неаккуратным с моей стороны, делал тесты на консоли и забыл это :) – Winchestro

1

Если определить свойства, используя Object.defineProperty указания только value вместо get и set, то вы используете data descriptor (см here). С data descriptor вы можете добавить свойство writable, чтобы указать, может ли свойство быть изменено или нет. По умолчанию writable=false.

Так что если вы указываете только value дескриптора данных, без writable: true - вы не можете изменить это свойство позже. Такое поведение не имеет ничего общего с ES6, поскольку в ES5 был введен Object.defineProperty.

Правильный код:

class hasDefault { 
    setValue (v) { 
    this.v = v; 
    } 
} 
Object.defineProperty(hasDefault.prototype, "v", { 
    value : 5, 
    writable: true, 
    enumerable : true 
}); 

let a = new hasDefault; 
console.assert(a.v === 5); 
a.setValue(2); 
console.assert(a.v === 2); 

Traceur REPL

+0

спасибо, вы ответили правильно но в моем случае путаница была скорее о наследовании дескриптора для экземпляра, а не о неприводимом для записи свойстве. – Winchestro

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

  • Нет связанных вопросов^_^