Рассмотрите возможность использования prototype
:
function JMath() {};
JMath.prototype = {
pi2: Math.PI,
foo: function() {
return this.pi2;
}
}
var j = new JMath();
j.pi2=44; j.foo(); // returns 44
delete j.pi2; j.foo(); // now returns Math.PI
Разница между этим и ответом @ altCognito заключается в том, что здесь поля объекта являются общими и все указывают на одно и то же. Если вы не используете прототипы, вы создаете новые и несвязанные экземпляры в конструкторе. Вы можете переопределить значение прототипа для каждого экземпляра, и если вы переопределите его, а затем решите, что вам не нравится значение переопределения и хотите восстановить оригинал, используйте delete
, чтобы удалить переопределение, которое просто "затеняет" Стоимость прототипа.
Редактировать: если вы хотите унаследовать все методы и поля самого объекта Math, но переопределить некоторые вещи, не затрагивая объект Math, сделайте что-то вроде этого (измените имя «Constructor1» по своему вкусу):
function Constructor1() {};
Constructor1.prototype = Math;
function JMath() {};
JMath.prototype = new Constructor1();
JMath.prototype.pi2 = JMath.prototype.PI;
JMath.prototype.foo = function() { return this.pi2; }
var j = new JMath();
j.cos(j.foo()); // returns -1
edit 3: объяснение функции Constructor1: Это создает следующую цепочку прототипов:
j -> JMath.prototype -> Math
j является экземпляром JMath. Прототип JMath является экземпляром Constructor1. Прототипом Constructor1 является Math. JMath.prototype - это то место, где «живет» переопределенный материал. Если вы реализуете только несколько экземпляров JMath, вы можете сделать переопределенные вещи переменными экземпляра, которые устанавливаются конструктором JMath, и указывать непосредственно на Math, как это делает ответ @ altCognito. (j является экземпляром JMath, а JMath - Math)
Есть два недостатка дополнения объекта в конструкторе. (На самом деле это не обязательно недостатки) Во-первых, объявление полей / методов экземпляра в конструкторе создает отдельные значения для каждого экземпляра. Если вы создаете много экземпляров JMath, функция JMath.foo каждого экземпляра будет отдельным объектом, занимающим дополнительную память. Если функция JMath.foo происходит из своего прототипа, то все экземпляры совместно используют один объект.
Кроме того, вы можете изменить JMath.prototype.foo после факта, и экземпляры будут обновлены соответствующим образом. Если вы делаете функцию foo в конструкторе как метод для каждого экземпляра, то после создания объектов JMath они становятся независимыми, и единственный способ изменить функцию foo - это изменить каждый из них.
edit 2: что касается свойств, доступных только для чтения, вы не можете реализовать их из самого Javascript, вам нужно разбираться под поверхностью. Однако вы можете объявить так называемые " getters ", которые эффективно действуют как константы:
JMath.prototype.__defineGetter__("pi2", function() { return Math.PI; });
JMath.prototype.__defineSetter__("pi2", function(){}); // NOP
var j = new JMath();
j.pi2 = 77; // gee, that's nice
// (if the setter is not defined, you'll get an exception)
j.pi2; // evaluates as Math.PI by calling the getter function
Предупреждение: синтаксис для определения методов получения / установки , по-видимому, не является чем-то, что IE не реализует красиво .