Прошлой ночью я прочитал статью на mdn о символах и обнаружил, что это здорово. Я всегда использовал какие-то псевдоклассы в Javascript с конструктором и прототипом и думал об использовании символов в качестве некоторого хранилища для частных объектов, свойств, методов, но после экспериментов и тестирования кажется, что spidermonkey очень медленно работает с символами как ключ объекта или я сделал что-то не так, но у меня нет этой проблемы с хромом.
Можете ли вы сказать мне, есть ли способ сделать более быстрый доступ к объектам по символам?
Допустим, я иметь псевдо-класс с конструктором и прототипом с именем test
//********************************************************
//-------------------------------------- Class test normal
//********************************************************
{//----------------------------------- BlockScope
//-----------------------------------------------------
//-------- constructor
//-----------------------------------------------------
let CONSTR=EFTA.Classes.test=function (x,y) //-- Short Reference CONSTR
{
var private_x=20, private_y=30, private_z=50, that=this;
function private_method () // has access to PRIVATE properties, methods
{
PROTO.public_calculation_counter++;
return that.public_x+that.public_y+private_x+private_y;
}
this.public_x=x;
this.public_y=y;
this.public_methodA=function () {return private_method ()+private_z;} //-- has access to PRIVATE properties, methods
}
//-----------------------------------------------------
//-------- constructor -- END
//-----------------------------------------------------
//-----------------------------------------------------
//-------- prototype
//-----------------------------------------------------
//-- Set Short Reference
let PROTO = CONSTR.prototype; //-- Short Reference to prototype
PROTO.public_calculation_counter=0; //-- property only linked on each instance
//-- normal public prototype method - has no access to PRIVATE properties
PROTO.public_methodB=function ()
{
return this.public_x*this.public_y;
}
//-----------------------------------------------------
//-------- prototype - END
//-----------------------------------------------------
} //-------------------------------- BlockScope -- END
//********************************************************
//-------------------------------------- Class test normal -- END
//********************************************************
public_methodB - это обычный метод прототипа, не имеющий доступа к объекту PRIVATE, методы и свойства public_methodA определены внутри конструктора, поэтому он имеет доступ к объекту PRIVATE, методы и свойства.
каждый раз, когда конструктор запускается, он генерирует новую функцию (private_method) и новую функцию (public_methodA), public_methodB связан только в прототипе
Теперь я хотел реорганизовать этот сценарий , так что public_methodA и private_method создаются только один раз и для всех экземпляров одинаково.
, поэтому я генерирую Symbol
EFTA.Classes.Symbols.priv=Symbol ();
этот ключ уникального идентификатора, который я сейчас использую для хранения private_ ( x | y | z) в экземпляре, подобном папке
const EFTA={};
EFTA.Classes={};
EFTA.Symbols=
{
dom :Symbol (), //-- storage key on dom elements
priv:Symbol () //-- storage key for private object, methods and properties
};
//**************************************************************
//-------------------------------------- Class test with Symbols
//**************************************************************
{//----------------------------------- BlockScope
//-----------------------------------------------------
//-------- constructor
//-----------------------------------------------------
let CONSTR=EFTA.Classes.test_with_Symbols=function (x,y) //-- Short Reference CONSTR
{
this.public_x=x;
this.public_y=y;
//-- instance folder for PRIVATE objects and properties existing on each instance - hided by Symbol
this[priv]=
{
private_x:20,
private_y:30,
private_z:50
}
}
//-----------------------------------------------------
//-------- constructor -- END
//-----------------------------------------------------
//-- Set Short References
let PROTO = CONSTR.prototype, //-- Short Reference to prototype
priv = EFTA.Symbols.priv; //-- Short Reference to Symbol (unique identifier)
, и теперь я установил public_methodA для прототипа, который был первым в конструкторе. теперь он может получить доступ к свойствам PRIVATE этим [priv], он связан только с экземпляром
//-----------------------------------------------------
//-------- prototype
//-----------------------------------------------------
PROTO.public_calculation_counter=0; //-- property only linked on each instance
PROTO.public_methodA=function () //-- method only linked on each instance
{
return privFolder.private_method.call (this)+this[priv].private_z; //-- call a PRIVATE method from a public method (prototype)
}
//-- normal public prototype method - has now also access to PRIVATE properties, methods over privFolder. (constructor Folder) or this[priv] (instance folder)
PROTO.public_methodB=function ()
{
return this.public_x*this.public_y;
}
//-----------------------------------------------------
//-------- prototype - END
//-----------------------------------------------------
, теперь я установил в конструкторе вторую папку с этим ключом уникального идентификатора, куда я поместил все методы PRIVATE здесь только один -> private_method
//-- constructor Folder for PRIVATE objects, methods and properties stored in the constructor (test) - hided by Symbol
CONSTR[priv]=
{
private_method: function () //--- private method not stored on each instance
{
PROTO.public_calculation_counter++;
return this.public_x+this.public_y+this[priv].private_x+this[priv].private_y;
},
private_test:"Hello World" //--- private property not stored on each instance - Additional
}
let privFolder=CONSTR[priv]; //-- Short Reference to the Folder on the constructor
этот private_method можно вызвать с privFolder.private_method.call (this), чем он имеет доступ к свойствам экземпляра publi c, а также к свойствам PRIVATE с помощью этого [priv ] каждого экземпляра.
я провел тест на https://jsfiddle.net/ThorstenArtnerAustria/7osf8kc9/15/
создал экземпляры с нормальным классом test Firefox: 876ms создал экземпляры с тестом класса с символами. Это быстрее, чем в два раза меньше Firefox: 376 мс
, чем то, что я выполнил public_methodA с тестом класса Firefox: 70 мс и public_methodA с тестом класса Символы Firefox: 523 мс
в chrome я получаю за создание 605 мс | 213 мс и для выполнения 85 мс / 115 мс
, если я изменяю в Firefox все это [priv] на этот ["priv"] с Symbol на обычный строковый идентификатор, я получаю 68ms, который был первым 523ms
Кажется, что доступ к символу очень медленный на объекте, или я что-то не так?