Переменные класса в JavaScript

Как сказал Дейв в своем комментарии, Sprite является ссылочным типом, поэтому Unity загружает спрайт в память один раз, а затем все другие экземпляры объектов, которые ссылаются на конкретную точку Sprite, на ее адрес памяти (как система указателей C). должно сработать). Так что в вашем случае, даже если вы создадите 1000 объектов из вашего объекта Scriptable, все они будут указывать на один и тот же Sprite.

Как правило, если вы используете Resources.Load() для объекта, то каждый загруженный объект будет использовать ту же ссылку на переменную, что и родительский объект Scriptable. Но если вы создаете новый объект каждый раз, когда вы хотите создать его, скажем, с помощью конструктора класса, то каждый объект (и впоследствии их переменные) будет иметь свое собственное пространство в памяти. В вашем случае это произошло бы, если бы вы использовали Sprite mySprite = new Sprite() каждый раз, когда создавали объект Scriptable.

Таким образом, нет памяти за добавление нескольких экземпляров одного и того же Sprite в ваши объекты Scriptable (использование CPU / GPU - другая проблема, не связанная с вашим вопросом, но, тем не менее, заслуживающая упоминания). Проверка вашей памяти может иметь изменяющиеся значения, если вы выполняете ее в своей игре вместе со всеми другими выполняемыми операциями, поэтому я предлагаю вам создать новый проект и затем попытаться измерить значения из инспектора. Если вы это сделаете, пожалуйста, поделитесь своими выводами здесь, так как это интересная тема.

Также, прочитайте этот пост из обмена стека GameDev для получения дополнительной информации по вашему вопросу.

17
задан esiegel 4 November 2008 в 16:48
поделиться

7 ответов

I assumed that since prototypes will be shared between objects then so will their variables.

Они, но это:

a.shared++

не делает то, что Вы думаете, что это делает. Это - на самом деле (приблизительно) сахарный синтаксис для:

(a.shared= a.shared+1)-1

(-1, являющиеся для возвращения преинкрементное значение, не, что Вы на самом деле используете значение возврата, но все еще.)

, Таким образом, это на самом деле делает присвоение на a.shared. Когда Вы присваиваете члену экземпляра, Вы всегда пишете в собственных участников того экземпляра, не касание любых членов любого из его прототипов. Это - то же что:

classA.prototype.shared= 1;
a.shared= 2;

, Таким образом, Ваш новый a.shared скрывает prototype.shared, не изменяя его. Другие экземпляры classA продолжили бы показывать значение прототипа 1. При удалении a.shared, Вы еще раз смогли бы видеть переменную прототипа, которая была скрыта позади него.

8
ответ дан 30 November 2019 в 12:01
поделиться

Статичный (уровень класса) переменные могут быть сделаны как это :

function classA(){
    //initialize
}

classA.prototype.method1 = function(){
    //accessible from anywhere
    classA.static_var = 1;
    //accessible only from THIS object
    this.instance_var = 2;
}

classA.static_var = 1;  //This is the same variable that is accessed in method1()

Ваш вывод кажется странным из-за способа, которым JavaScript обрабатывает прототипы . Вызов любого метода / получение переменной инстанцированного объекта проверки экземпляр сначала, ЗАТЕМ прототип . т.е.

var a = new classA();
classA.prototype.stat = 1;

// checks a.stat which is undefined, then checks classA.prototype.stat which has a value
alert(a.stat); // (a.stat = undefined, a.prototype.stat = 1)

// after this a.stat will not check the prototype because it is defined in the object.
a.stat = 5;  // (a.stat = 5, a.prototype.stat = 1)

// this is essentially a.stat = a.stat + 1;
a.stat++; // (a.stat = 6, a.prototype.stat = 1) 
15
ответ дан 30 November 2019 в 12:01
поделиться

Если Вы хотите иметь переменную класса, что-то как статическая переменная в Java, то можно объявить переменную в родительском классе, но затем Вы не должны получать доступ к нему как к переменной дочерних объектов. Эта статья имеет хороший пример класса Круг, имеющий переменную Circle.PI = 3.14 в то время как все экземпляры Кругового доступа это как Circle.PI (вместо c.PI).

, Таким образом, мой ответ - то, что, если Вы хотите иметь переменную класса shared в classA затем, необходимо объявить переменную, совместно использованную в classA, и позже необходимо использовать classA.shared вместо a.shared. Изменение a.shared никогда не будет приводить к classA.shared изменяемый.

5
ответ дан 30 November 2019 в 12:01
поделиться

Вы просто исправляете участника на "классе", который в JavaScript является функцией, которая создает объекты:

function ClassA(x) { this.x = x; }
ClassA.shared = "";
ClassA.prototype.foo = function() {
    return ClassA.shared + this.x;
}

var inst1 = new ClassA("world");
var inst2 = new ClassA("mars");

ClassA.shared = "Hello ";
console.log(inst1.foo());
console.log(inst2.foo());
ClassA.shared = "Good bye ";
console.log(inst1.foo());
console.log(inst2.foo());
3
ответ дан 30 November 2019 в 12:01
поделиться

Постепенное увеличение shared свойство через экземпляр делает это свойством того экземпляра, который является, почему Вы видите это поведение.

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

>>> function ConstructorA() {};
>>> ConstructorA.prototype.shared = 0;
>>> var a = new ConstructorA();
>>> ConstructorA.prototype.shared++;
>>> a.shared
1
>>> a.hasOwnProperty("shared")
false
>>> a.shared++;
>>> a.hasOwnProperty("shared")
true

Поэтому правильное решение состоит в том, чтобы использовать ConstructorA.shared, как предложено во многих ответах до сих пор, и всегда получать доступ к нему через функцию конструктора, не экземпляр.

Это могло бы помочь полагать, что нет такой вещи как класс в JavaScript. "Экземпляры" создали с new, оператор является просто объектами, которые были созданы конкретной функцией конструктора и имеют конкретную опытную цепочку. Поэтому a.shared не сможет получить доступ ConstructorA.shared - доступ свойства включает рассмотрение рассматриваемого объекта для именованного свойства и сбоя, что, обходя его опытный поиск цепочки свойства, но функция конструктора, которая создала объект, не является частью опытной цепочки.

2
ответ дан 30 November 2019 в 12:01
поделиться

То, что Вы определяете, не является переменной класса, это - значение по умолчанию для переменной экземпляра.

Переменные класса должны быть определены непосредственно в классе, что означает непосредственно в функции constrctor.

function ClassA()
{
    ClassA.countInstances = (ClassA.countInstances || 0) + 1;
}
var a1 = new ClassA();
alert(ClassA.countInstances);
var a2 = new ClassA();
alert(ClassA.countInstances);

, Когда Вы объявляете переменную в прототипе, эта переменная будет наследована всеми экземплярами как переменные экземпляра (точно так же, как методы), и будет ve, переопределенный при изменении его в экземпляре (точно так же, как методы).

0
ответ дан 30 November 2019 в 12:01
поделиться

Если Вы инстанцируете того класса (a = new classA), то изменение того экземпляра a не изменит сам базовый класс. Экземпляры classA наследуют все от classA.prototype, но это не применяется назад, изменение a не изменится classA.
, Если у Вас есть два экземпляра как a1 = new classA и a2 = new classA затем, можно внести изменения и в a1 и в a2, не производя другой. Изменение classA.prototype, с другой стороны, будет видимо в них обоих.
переменная shared из экземпляра a будет иметь значение по умолчанию, пока этому не дадут новое значение. Значение по умолчанию является значением [1 113].

1
ответ дан 30 November 2019 в 12:01
поделиться
Другие вопросы по тегам:

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