2015-01-29 6 views
1

Как удалить свойство p из прототипа объекта?Как переопределить свойство из прототипа?

var Test = function() {}; 
Object.defineProperty(Test.prototype, 'p', { 
    get: function() { return 5; } 
}); 

Object.defineProperty(Test.prototype, 'p', { 
    get: function() { return 10; } 
}); 

Это производит TypeError: Невозможно переопределить свойство: р. Есть ли способ удалить свойство и повторно добавить его? Или можно установить атрибут configurable после создания свойства?

+1

Уверенный, вам необходимо определить его как настраиваемый. –

+0

Исходное определение не мое, поэтому я не могу этого сделать. Свойство определено во внешней библиотеке. – stackular

+0

Можете ли вы расширить цепочку прототипов на один уровень глубже (наследовать от Test и поместить ваше свойство посередине) или переопределить его в экземпляре (то есть выполнить функцию MyTest() {t = new Test(); tp = ... ; return t;} ' –

ответ

2

Если вы в состоянии выполнить код перед кодом вы хотите избежать, вы можете попробовать угон Object.defineProperty, чтобы предотвратить добавление этого имущества:

var _defineProperty = Object.defineProperty; 
Object.defineProperty = function(obj, prop, descriptor) { 
    if(obj != Test.prototype || prop != 'p') 
     _defineProperty(obj, prop, descriptor); 
    return obj; 
}; 

Или вы можете сделать это настраивается, чтобы быть в состоянии изменить его позже:

var _defineProperty = Object.defineProperty; 
Object.defineProperty = function(obj, prop, descriptor) { 
    if(obj == Test.prototype && prop == 'p') 
     descriptor.configurable = true; 
    return _defineProperty(obj, prop, descriptor); 
}; 

в конце концов, вы можете восстановить оригинальный один:

Object.defineProperty = _defineProperty; 
+1

Это * ужасное * решение, но это единственное, что я нашел и, похоже, работает нормально, поэтому я поеду с ним. – stackular

1

Вы пробовали что-то вроде этого? Он должен был запускаться до создания новых Test экземпляров.

var Test = function() {}; 

Object.defineProperties(Test.prototype, { 
    p: { 
     get: function() { 
      return 5; 
     } 
    }, 

    a: { 
     get: function() { 
      return 5; 
     } 
    } 
}); 

Test.prototype = Object.create(Test.prototype, { 
    p: { 
     get: function() { 
      return 10; 
     } 
    } 
}); 

var t = new Test(); 

console.log(t.a, t.p); 
+0

Это должно работать, и вы можете определить свойство как аргумент ['Object.create'] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create) вместо вызова 'Object.defineProperty' впоследствии. http://jsfiddle.net/Xotic750/j66peg0z/ – Xotic750

+0

@ Xotic750 Да, я просто слишком ленился, чтобы не копировать/вставлять, так что еще раз я просто копировал/вставлял ваши;) – plalx

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