JavaScript - Предимства на обектния литерал

Чел съм, че вместо просто да пиша куп функции, трябва да използвам обектен литерал.

Може ли някой да обясни какви са предимствата на обектния литерал с примери, защото досега не разбирам.

Благодаря


person Jourkey    schedule 21.10.2009    source източник


Отговори (4)


Както каза Russ Cam, вие избягвате замърсяването на глобалното пространство от имена, което е много важно в наши дни на комбиниране на скриптове от множество местоположения (TinyMCE и т.н.).

Както каза Алекс Секстън, това допринася и за добра организация на кода.

Ако използвате тази техника, бих предложил да използвате модела на модула. Това все още използва обектни литерали, но като върната стойност от функция за обхват:

var MyThingy = (function() {

    function doSomethingCool() {
        ...
    }

    function internalSomething() {
        ....
    }

    function anotherNiftyThing() {
        // Note that within the scoping function, functions can
        // call each other direct.
        doSomethingCool();
        internalSomething();
    }

    return {
        doSomethingCool: doSomethingCool,
        anotherNiftyThing: anotherNiftyThing
    };
})();

Външна употреба:

MyThingy.doSomethingCool();

Функцията за обхват е обвита около всички ваши функции и след това я извиквате незабавно и съхранявате нейната върната стойност. Предимства:

  • Функциите се декларират нормално и следователно имат имена. (Докато с формата {name: function() { ... }} всички ваши функции са анонимни, въпреки че свойствата, които ги препращат, имат имена.) Помощните инструменти за имена ви помагат, от показване на стекове на повиквания в програма за отстраняване на грешки, до това да ви кажат коя функция е хвърлила изключение. (Актуализация от 2015 г.: Най-новата спецификация на JavaScript, ECMAScript 6-то издание, дефинира голям брой начини, по които машината на JavaScript трябва да изведе името на функция. Един от тях е, когато функцията е присвоена на свойство, както в нашия {name: function() { ... }} пример. Тъй като двигателите прилагат ES6, тази причина ще изчезне.)
  • Дава ви свободата да имате частни функции, използвани само от вашия модул (като моя internalSomething по-горе). Никой друг код на страницата не може да извика тези функции; те са наистина частни. Само тези, които експортирате в края, в израза за връщане, са видими извън функцията за обхват.
  • Улеснява връщането на различни функции в зависимост от средата, ако внедряването просто се промени напълно (като IE-срещу-W3C неща или SVG срещу Canvas и т.н.).

Пример за връщане на различни функции:

var MyUtils = (function() {
    function hookViaAttach(element, eventName, handler) {
        element.attachEvent('on' + eventName, handler);
    }

    function hookViaListener(element, eventName, handler) {
        element.addEventListener(eventName, handler, false);
    }

    return {
        hook: window.attachEvent ? hookViaAttach : hookViaListener
    };
})();

MyUtils.hook(document.getElementById('foo'), 'click', /* handler goes here */);
person T.J. Crowder    schedule 21.10.2009
comment
Когато създавате екземпляр на функция по анонимен начин, все пак можете да й дадете име (var x = function x() { ... }). Когато направите това, името се обвързва така, че да е достъпно за рекурсивни препратки във функцията. - person Pointy; 21.10.2009
comment
@Pointy: Не можете да направите това (използвайте име на функция в рамките на присвояване) междубраузър, не работи правилно нито в IE, нито в Safari; подробности: yura.thinkweb2.com/named-function-expressions И вие не няма нужда, правилното име на функцията (foo в function foo) е в обхвата в целия обхват, където е декларирана, включително в самата функция, така че foo може да се извика сама чрез символа foo, няма нужда да присвоявате препратка към функцията нещо (в този момент). - person T.J. Crowder; 21.10.2009
comment
(Продължаване) Разбира се, че би било хубаво да можете да използвате както присвояване, така и собствено име едновременно, защото това би улеснило експортирането на функции от функцията за обхват. Спецификацията със сигурност го позволява, но за съжаление, практичните аспекти (бъгове при внедряването) влизат в него. - person T.J. Crowder; 21.10.2009

Използването на обектен литерал (известен още като модел на обектен литерал) няма да замърси глобалното пространство от имена толкова сериозно, колкото използването на много функции, декларирани глобално, и също така помага да се организира кодът по логичен начин

Например този обектен литерал

var obj = {
              find : function(elem) { /* find code */ },
              doSomething: function() { /* doSomething code */ },
              doSomethingElse: function() { /* doSomethingElse code */ }
          }

в сравнение с

function find(elem) { /* find code */ },
function doSomething() { /* doSomething code */ },
function doSomethingElse() { /* doSomethingElse code */ }

ще създаде само едно свойство на глобалния обект в сравнение с три. След това можете лесно да използвате функциите по този начин

obj.doSomething();
person Russ Cam    schedule 21.10.2009
comment
можете просто да напишете много функции в една нормална функция и да не замърсявате кода си. обектният литерал не дава никаква добавена стойност. Аз самият използвам метода на прототипа.. - person vsync; 30.11.2009

Ребека Мърфи изнесе лекция за обектни литерали на тазгодишната jQuery конференция. Една от най-добрите причини да ги използвате е просто добрата организация на кода.

Ето написаното от Ребека за модела на буквалния обект: http://rmurphey.com/blog/2009/10/15/using-objects-to-organize-your-code/

person Alex Sexton    schedule 21.10.2009
comment
Друга страхотна статия за обектните литерали: wait-till-i.com/2006/02/16/show-love-to-the-object-literal - person Alex Sexton; 21.10.2009

Винаги съм използвал обектни литерали, защото те са ясен начин за организиране на код. Ето защо не харесвам прототипа, твърде е разхвърлян.

Функциите не замърсяват пространството на имената, както някой спомена по-горе, повече от обектните литерали.

Можете лесно да напишете буквално харесване

var obj = {}
var find = function(elem) { /* find code */ },
var doSomething = function() { /* doSomething code */ },
var doSomethingElse = function() { /* doSomethingElse code */ }

което ще замърси чрез създаване на много глобални обекти, същите като функциите. по подобен начин можете да направите:

(function() {
function find(elem) { /* find code */ },
function doSomething() { /* doSomething code */ },
function doSomethingElse() { /* doSomethingElse code */ }
})();

което не би създало тези глобални обекти (всичко е обект в JS)

по този начин все още не създавате много глобални обекти.

Според мен обектните литерали имат две предимства. Едно от тях се използва от много плъгини като jQuery, така че хората са по-познати и са лесни за четене. Правейки ги лесни за предаване на данни в плъгин. Лесно е да създавате както публични, така и частни методи....

Те обаче могат да бъдат бавни, тъй като всеки път, когато създавате екземпляр на обекта, всички негови методи се дублират. Доколкото разбирам, това не е така с прототипа, тъй като имате едно копие на методите и новите обекти просто препращат към прототипа.

Може и да греша разбира се...

person monkey panther    schedule 09.11.2013
comment
Обектните литерали са добри за пространство на имена и сингълтони, когато създавате множество екземпляри на обект със споделено поведение, тогава би било по-добре да използвате конструкторски функции. Не съм намерил случай на употреба, при който да консумирам повече процесор и памет чрез симулиране на лични начини, използвайки _myPrivate вместо това, но ще се радвам, ако някой може да ми предостави такъв. Повече за прототипа, наследяването, миксовете тук: stackoverflow.com/a/16063711/1641941 - person HMR; 09.11.2013