Страницы

Поиск по вопросам

понедельник, 22 октября 2018 г.

В чем разница вызовов(обьявлений) этих обьектов?

Добрый вечер, начал изучать js около месяц назад, начал с видеокурсов Специалист. В общем там обьекты обьявлялись и вызывались такими вот способами: 1) var iamobj=new Object; iamobj.name="giggity"; iamobj.show=function(){ alert(this.name); }
iamobj.show(); ну здесь понятно, обьявили обьект, обьявили свойство и метод, затем вызвали метод 2) function Test(name){ this.name=name; this.show=function(){ alert(this.name) } }
var iamobj=new Test("giggity"); iamobj.show(); что имеем здесь: снизу обьявили обьект и сразу-же присвоили ему функцию, куда передали значение, затем вызвали метод Здесь вроде бы как все понятно, не ясно только какой метод когда лучше использовать.. но затем начал вчитываться в статью про свойства и методы обьектов на javascript.ru и вообще запутался синтаксис совершенно другой.. сейчас покажу 3) var iamobj={ read:function(){ this.name=prompt("имя?") }, show:function(){ return this.name } }
iamobj.read(); alert(iamobj.show()) собственно.. вопрос.. что это вообще такое и зачем? внизу сразу вызывается метод у обьекта iamobj, потом поднимаемся вверх и только тут обьявляем обьект (var), считываем значения имени в методе.. и снизу вызываем еще один метод чтобы показать. между методами в обьекте обьязана стоять запятая.. зачем столько вариатов обьявлений? у каждого из них есть какое-то преимущество в определенном условии? 4) function show(){ this.name=name; alert(this.name); }
var iamobj=new show("giggity") снизу обьявили обьект, тут же вызвали ф-цию и передали в нее значение, та берет значение, присваивает и выводит.. легкий способ, но опять же, синтаксис другой 5) function iamobj(){ this.show=function(){ var a=prompt("name?") alert(a); } }
new iamobj().show(); опять же новый синтаксис, внизу обьявляем обьект и тут же пишем какой метод в нем хотим вызвать, обьект являетсо функцией(?), внутри которого каждое свойство = метод (так чтоли? зачем?) в общем, обьясните кто-то пожалуйста зачем столько вариантов разных есть и в чем преимущество каждого? хотя бы приблизительно, ато я что-то вообще уже теряюсь


Ответ

Столько возможностей объявления для нашего с вами удобства, правда что касается примера инициализации объекта с помощью ключевого слова new - это нечто иное, если быть точным то это одна из возможных реализаций ООП, раз уже задел этот вопрос - немного о концепции. Любая функция может вызываться при помощи оператора new, функция, далее конструктор, которая вызывается при помощи оператора new получает на вход переменную this которая является еще не созданным объектом (который она, собственно и вернет), в контексте ООП - экземпляром "класса". Не смотря на похожий синтаксис - ООП в javascript устроено не так как везде, если быть более точным - построено на прототипировании. Теперь непосредственно о прототипах - у любой функции есть прототип (если быть точным у любого объекта, но в нашем случае речь не об этом), прототип это объект к которому имеют доступ все экземпляры конструктора("класса") ( сам по себе он всего-лишь JavaScript объект ), в котором целесообразно хранить общие методы или свойства для всех экземпляров конструктора("класса"). Что же касается специфических свойств и методов - их необходимо (читай по хорошему) инициализировать в конструкторе. Важно добавить - prototype это 1 единственный объект, независимо от количества экземпляров, соответственно, если, например, писать так: var User = function( username ) { this.__username = username; this.getUsername = function(){ return this.__username; } this.setUsername = function( username ){ this.__username = username; } }
var user1 = new User('Vasya'); var user2 = new User('Petya'); В этом случае - методы getUsername и setUsername делают одну и ту-же работу, но, что касаемо памяти - это разные функции, в этом можно легко убедиться: alert( user1.getUsername === user2.getUsername ) // false alert( user1.setUsername === user2.setUsername ) // false Соответственно с точки зрения памяти и вообще здравого смысла - этот подход не лучшее решение. Но теперь о том как все это нужно делать в javascript'e, перепишем пример var User = function( username ) { this.__username = username; } User.prototype = { getUsername : function(){ return this.__username; }, setUsername : function( username ){ this.__username = username; } }
var user1 = new User('Vasya'); var user2 = new User('Petya');
alert( user1.getUsername === user2.getUsername ); // true alert( user1.setUsername === user2.setUsername ); // true Как мы видим - использовав прототип мы добились того что наши методы getUsername и setUsername не плодятся для каждого вызова конструктора, а инициализируются единожды, что уже совсем другое дело с точки зрения памяти и здравого смысла. Ну а что касаемо разницы между записями вида var obj;
obj = {}; obj.somePropName = someValue; // ........
obj = { somePropName : someValue, // ........ };
obj = new Object(); obj.somePropName = someValue; // ........ Отличия нет, по крайней мере с точки зрения производительности. Есть разница только с точки зрения работы геттеров и сеттеров в контексте глобального конструктора Object, но я не думаю что вам это принципиально. По поводу последнего примера, на самом деле, грубо, происходит следующее: function iamobj(){ this.show=function(){ var a = prompt("name?") alert(a); } }
// new iamobj().show(); var obj = new iamobj(); obj.show(); Точно так-же мы могли бы поступить, например, с DOM элементом: document.getElementById("someElementId").onclick = function(){ /* observer code here... */ } С точки зрения целесообразности - применимо только в том случае, если объект не будет использоваться далее, и даже не смотря на это Крокфорд (и я за компанию), все-же, советуют заранее объявлять переменные перед тем как с ними работать. Если вам нужен статический метод, то просто используйте объект без вызова функции в контексте конструктора с помощью new (что-то типа iamobj.show = function(){/*...*/}, iamobj.show()). Вообще надо понимать что и для чего используется, если отбросить new и все из него выплывающее - объект это всего-лишь хэш, то что в объекте могут храниться функции - особенность языка, то что функции хэша имеют доступ в теле функции к хэшу через перменную this - так-же особенности языка, благодаря им можно городить пространства имен и легко и без напряга писать singleton'ы (и многое другое), но, как-бы там не было - в своем элементарном проявлении это всего-лишь ассоциативный массив. Надеюсь этой информации достаточно, пожалуй прекращаю т.к. и так ответ "немного" растянулся.

Комментариев нет:

Отправить комментарий