2009-10-21 21 views
38

Bunu bir demet işlevden çok yazmak yerine, nesne değişmezini kullanmalıyım.JavaScript - Nesne hazırlamasının avantajları

Nesne edebi avantajlarının örneklerle ne olduğunu açıklayabilir, çünkü şu ana kadar anlamıyorum. (Aka değişmezi desen nesne) değişmez bir nesne kullanarak

Teşekkür

cevap

64

Russ Cam dediği gibi, vb birden çok yerde (TinyMCE, komut dosyalarını birleştirerek bu günlerde çok önemlidir genel ad alanını, kirliliğine yol açmaması).

Alex Sexton'ın dediği gibi, iyi bir kod organizasyonu da yapar.

Bu tekniği kullanıyorsanız, modül desenini kullanmanızı öneririm. Bu hala nesne değişmezleri kullanır, ancak bir kapsam işlevinden dönüş değeri olarak:

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 
    }; 
})(); 

Dış kullanım:

MyThingy.doSomethingCool(); 

kapsam işlevi fonksiyonların her yerinde sarılır ve sonra hemen diyoruz ve dönüş değerini saklayın. Avantajları:

  • Fonksiyonlar normalde ilan ve dolayısıyla isimleri sahiptir. ({name: function() { ... }} biçiminde iken, tüm işlevleriniz anonimdir, bunlara başvurulan özelliklerin adları olsa bile.) Adlar yardımcı araçlar, bir hata ayıklayıcısındaki çağrı yığınlarını göstererek, hangi işlevi bir istisna attığınızı belirtmenize yardımcı olur. (2015 Güncelleştirmesi: En son JavaScript belirtimi olan ECMAScript 6. sürümünde, JavaScript motorunun değerini bir işlevin adına girmesi gerekir. Bunlardan biri, işlevin bir özelliğe {name: function() { ... }} örneğindeki gibi atanmasıdır. motorlar ES6 uygular, bu sebeple gider.)
  • Size sadece sizin modülünüz tarafından kullanılan özel işlevlere sahip olma özgürlüğü verir (yukarıdaki internalSomething gibi). Sayfadaki başka hiçbir kod bu işlevleri çağırmaz; gerçekten özeller. Yalnızca sonuçta dışa aktardığınız, dönüş ifadesinde, kapsam belirleme işlevinin dışında görünür.
  • Uygulama tamamen değiştiğinde (örneğin IE-vs-W3C nesneleri veya SVG vs Canvas vb.), Çevreye göre farklı işlevler döndürmeyi kolaylaştırır. farklı işlevler dönüş

Örnek: onlar kodunu düzenlemek için net bir yoldur çünkü

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 */); 
+2

Bir işlevi "anonim" şekilde başlattığınızda, yine de bir ad verebilirsiniz (var x = function x() {...}). Bunu yaptığınızda, ad, işlev içindeki özyinelemeli referanslar için kullanılabilir olacak şekilde bağlanır. – Pointy

+1

@Pointy: Bunu (tarayıcıda bir işlev adı kullanın) çapraz tarayıcı yapamazsınız, IE veya Safari'de düzgün çalışmıyor; ayrıntıları: http://yura.thinkweb2.com/named-function-expressions/ Ve gerek yok, fonksiyonun uygun ismi (foo 'foo' foo ') kapsamı tüm kapsamı içinde kapsamı Fonksiyonun kendisi dahil olmak üzere, beyan edilir, bu yüzden foo, 'foo' sembolü ile kendini çağırır, fonksiyon referansını herhangi bir şeye atamaya gerek yoktur (bu noktada). –

+0

(Devam ediyor) Verilerin hem kapsamlama hem de uygun isimleri aynı anda kullanabilmesi için * güzel * olması, işlevlerin kapsam belirleme işlevinden daha kolay aktarılmasını sağlar. Spec kesinlikle buna izin verir, ama ne yazık ki, pratiklikler (uygulama hataları) içine girer. –

15

olacak global olarak deklare birçok işlevi kullanmak kadar ciddi genel ad alanını kirletmez, hem de mantıksal bir biçimde

için kod düzenlemek için yardımcı olur olmaz

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

değişmez örneğin, bu amaç,

function find(elem) { /* find code */ }, 
function doSomething() { /* doSomething code */ }, 
function doSomethingElse() { /* doSomethingElse code */ } 
ile karşılaştırıldığında

, global nesnedeki üç taneye kıyasla yalnızca bir özellik oluşturacaktır. Bu yılki jQuery Konferansı'nda Nesne rakamları üzerinde bir konuşma Daha sonra kolayca böylece

obj.doSomething(); 
+2

Tek bir normal işlevde çok işlev yazabilir ve kodunuzu kirletemezsiniz. nesne değişmezi herhangi bir katma değer vermez. Ben kendim prototip yöntemini kullanıyorum .. – vsync

9

Rebecca Murphey gibi işlevleri kullanabilirsiniz yaptı. Bunları kullanmanın en iyi sebeplerinden biri, iyi bir kod organizasyonudur. İşte

Nesne Değişmez Pattern Rebecca yazma kalmıştır: http://rmurphey.com/blog/2009/10/15/using-objects-to-organize-your-code/

+2

Nesne hazırlıkları hakkında başka bir harika makale: http://www.wait-till-i.com/2006/02/16/show-love-to-the-object-literal/ –

2

seni hep nesne değişmezleri kullandı. Bu yüzden prototipten hoşlanmıyorum, çok dağınık.

İşlevler, yukarıda belirtilen nesne boşluklarından daha fazla biri olarak adlandırılan ad alanını yormaz.

Kolayca işlevleriyle aynı aynı küresel nesnelerin sürü oluşturarak kirletmez olacaktır

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

gibi bir hazır yazabilirim. Benzer bunu yapabilirsiniz: (herşey JS bir nesnedir)

hala küresel nesnelerin yükleri oluşturmadığından emin şekilde bu küresel nesneler yaratmak olmaz

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

.

Aklım nesnelerine, iki avantajı vardır. Bir tanesi jQuery gibi birçok eklenti tarafından kullanılıyor, böylece insanlar daha kolay ve okunması kolay. Verileri bir eklentiye aktarmayı kolaylaştırmak. Hem özel hem de özel yöntemleri oluşturmak çok kolaydır.

Nesnelerin bir örneğini oluşturduğunuz her yöntem çoğaltıldığında her zamanki gibi yavaş olabilirler. Bu benim prototiple ilgili bir çözümün ve prototip referansı olarak yeni bir çıktının olduğu gibi prototipte durum böyle değil.

Hatalı olabilirim ...

+1

Nesne değişmezleri adpacing ve singletons için iyidir, paylaşılan davranışı olan bir nesnenin birden çok örneğini oluşturduğunuzda, kurucu işlevlerini kullanmak daha iyi olur. Özel durum için '_myPrivate' kullanma yollarını dışarıda bırakarak daha fazla işlemci ve bellek tüketen, ancak birisinin bana bir tane sağlayabilmesi için mutlu olacak bir kullanım örneği bulamadım. Prototip, devralma hakkında daha fazla bilgi için buraya tıklayın: http://stackoverflow.com/a/16063711/1641941 – HMR

İlgili konular