Sombressoul
@Sombressoul

Исчезающий геттер — баг или фича?

Собственно, вместо тысячи слов:
var TestObj                     = {};
    TestObj.Trigger             = false;
    TestObj.SomeValue           = undefined;
    //TestObj._SomeValue_buffer   = undefined; /* если раскомментить, всё будет ок; или если удалить "TestObj._SomeValue_buffer = false;" в коде ниже; */

var SomeValue_setter    = function( v ){
    if ( TestObj.Trigger ){
        TestObj._SomeValue = v;
    } else {
        TestObj._SomeValue_buffer = v;
    }
};

var SomeValue_getter = function( v ){
    
    if ( TestObj._SomeValue === undefined ){
        TestObj._SomeValue = 10;
    }
    
    return TestObj._SomeValue;
};

TestObj.__defineSetter__( 'SomeValue' , SomeValue_setter );
TestObj.__defineGetter__( 'SomeValue' , SomeValue_getter );

TestObj.SomeFunction = function(){

    TestObj.Trigger = true;
    
    if ( TestObj._SomeValue_buffer ){
        TestObj.SomeValue = TestObj._SomeValue_buffer;
        TestObj._SomeValue_buffer = false; /* если грохнуть эту строку - всё будет ок; или если раскомментить "TestObj._SomeValue_buffer = undefined;" в коде выше; */
    }
    
}

TestObj.SomeValue = 15; /* инициализируем TestObj._SomeValue_buffer */

console.log( 'Before: ' );
console.log( TestObj.SomeValue ); /* 10 - ok */
console.log( TestObj._SomeValue ); /* 10 - ok */
console.log( TestObj._SomeValue_buffer ); /* 15 - ok */
console.log( 'setter/getter: ' + !!TestObj.__lookupSetter__( 'SomeValue' ) + '/' + !!TestObj.__lookupGetter__( 'SomeValue' ) ); /* true/true - ok */


TestObj.SomeFunction();

console.log( 'After: ' );
console.log( TestObj.SomeValue ); /* UNDEFINED - упс!.. должно быть 15 */
console.log( TestObj._SomeValue ); /* 15 - ok */
console.log( TestObj._SomeValue_buffer ); /* false - ok */
console.log( 'setter/getter: ' + !!TestObj.__lookupSetter__( 'SomeValue' ) + '/' + !!TestObj.__lookupGetter__( 'SomeValue' ) ); /* true/FALSE - упс!... испарился геттер */

// Chrome: 30.0.1599.101 m



Тот же код под FF 24.0 работает вполне предсказуемо и геттер никуда не исчезает. Можно было бы списать на область видимости переменных (TestObj._SomeValue_buffer используется только в сеттере и не объявлен в шапке), но мы же всё равно явно обращаемся к пространству имён TestObj, да и этот исчезающий геттер…


В общем, если кто в курсе, почему оно работает именно ТАК, а не иначе — объясните, пожалуйста. Если это всё же моя ошибка, а не баг, конечно.
  • Вопрос задан
  • 3001 просмотр
Решения вопроса 1
sigod
@sigod
Намесили вы тут лишнего.

Убивает геттер не присвоение _SomeValue_buffer, а то что входящий тип отличается от текущего. Попробуйте после TestObj.SomeValue = 15; сделать TestObj.SomeValue = true; // or anything except numbers — геттер сразу же отваливается. Попробуйте сделать по другому, например, сразу присвоить true, а потом, что угодно отличное от boolean — опять не стало геттера.

Я вот зашел сейчас на MDN почитать про __defineGetter__, а там предупреждения:
Non-standard
This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.
Deprecated
This feature has been removed from the Web. Though some browsers may still support it, it is in the process of being dropped. Do not use it in old or new projects. Pages or Web apps using it may break at any time.
Я так полагаю — это уже не баг.

P.S. Судя по именам переменных — ваш основной язык C#?
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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