Предположим, что у меня есть объект Foo
Как я могу расширить этот объект, добавив метод bar()
, а также убедиться, что в будущих экземплярах Foo
есть этот метод?
Предположим, что у меня есть объект Foo
Как я могу расширить этот объект, добавив метод bar()
, а также убедиться, что в будущих экземплярах Foo
есть этот метод?
вам нужно добавить его в прототип Foo:
function Foo(){}
Foo.prototype.bar = function(){}
var x = new Foo()
x.bar()
Все зависит от того, как вы создаете Foo
, и как вы собираетесь использовать .bar()
.
Во-первых, вы используете функцию-конструктор для своего объекта?
var myFoo = new Foo();
Если да, то вы можете расширить свойство Foo
function prototype
с помощью .bar
, например:
function Foo () { /*...*/ }
Foo.prototype.bar = function () { /*...*/ };
var myFoo = new Foo();
myFoo.bar();
Таким образом, каждый экземпляр Foo
теперь имеет доступ к экземпляру SAME .bar
.
Для этого: .bar
будет иметь ПОЛНЫЙ доступ к this
, но в функции конструктора не имеет доступа: variables
:
function Foo () { var secret = 38; this.name = "Bob"; }
Foo.prototype.bar = function () { console.log(secret); };
Foo.prototype.otherFunc = function () { console.log(this.name); };
var myFoo = new Foo();
myFoo.otherFunc(); // "Bob";
myFoo.bar(); // error -- `secret` is undefined...
// ...or a value of `secret` in a higher/global scope
По-другому вы можете определить функцию для возврата любого объекта (не this
), с .bar
, созданным как свойство этого объекта:
function giveMeObj () {
var private = 42,
privateBar = function () { console.log(private); },
public_interface = {
bar : privateBar
};
return public_interface;
}
var myObj = giveMeObj();
myObj.bar(); // 42
Таким образом, у вас есть функция, которая создает новые объекты.
Каждый из этих объектов имеет созданную для них функцию .bar
.
Каждая функция .bar
имеет доступ через то, что называется замыканием, к переменным "private" внутри функции, которая вернула их конкретный объект.
Каждый .bar
по-прежнему имеет доступ к this
, а this
, когда вы вызываете функцию типа myObj.bar();
, всегда ссылается на myObj
(public_interface
, в моем примере Foo
).
Недостатком этого формата является то, что если вы собираетесь создавать миллионы этих объектов, это также миллионы копий .bar
, которые будут потреблять в памяти.
Вы также можете сделать это внутри функции конструктора, установив this.bar = function () {};
внутри конструктора - опять же, потенциал роста - это закрытие-доступ к закрытым переменным в конструкторе, а недостаток - повышенные требования к памяти.
Итак, первый вопрос:
Ожидаете ли вы, что ваши методы будут иметь доступ к данным чтения/изменения "private", к которым нельзя получить доступ через сам объект (через this
или myObj.X
)?
а второй вопрос: Вы делаете достаточно этих объектов, чтобы память была большой проблемой, если вы даете им каждую свою личную функцию, а не даете им поделиться ими?
Например, если вы дали каждому треугольнику и каждой текстуре свою собственную функцию .draw
в высококачественной 3D-игре, которая может быть излишней, и это, скорее всего, повлияет на частоту кадров в такой деликатной системе...
Если, однако, вы хотите создать 5 полос прокрутки на страницу, и вы хотите, чтобы каждый из них мог установить свою позицию и отслеживать, если она перетаскивается, не позволяя каждому другому приложению иметь доступ к чтению/набору те же самые вещи, тогда действительно нет причин бояться, что 5 дополнительных функций собираются убить ваше приложение, предполагая, что оно может уже составлять 10 000 строк (или больше).
Существует много способов создания повторно используемых объектов, подобных этому в JavaScript. Mozilla имеет приятное введение здесь:
В вашем примере будет работать следующее:
function Foo(){
this.bar = function (){
alert("Hello World!");
}
}
myFoo = new Foo();
myFoo.bar(); // Hello World
Вы можете сделать bar функцией, сделав ее методом.
Foo.bar = function(passvariable){ };
В качестве свойства ему просто будет назначена строка, тип данных или логическое
Foo.bar = "a place";