2010-07-10 11 views
5

JavaScript nesnelerini olabildiğince sezgisel olarak yapıp yapılamayacağımı ve mümkün olduğunca doğru olduğundan emin olup olmadığımı görmeye çalışıyorum. Crockford'un JSLint.com'undan bir sürü farklı senaryo çalıştırıyorum ve çok şansım olmadı. Bir hatayı düzeltmek istiyorum, o zaman değişim nedeniyle başka bir şey ortaya çıkıyor. Aşağıda alabildiğim kadar iyi. Bunun üzerinde başka kimse var mı?Bir JavaScript nesnesi oluşturmanın en iyi yolu bu şekilde çalışır ve JSLint'i geçirir?

function gizmo(id) { 

    /* private variables */ 

    var myId = id; 

    /* private methods */ 

    var init = function() { 
    if (myId < 1) { 
     setId(1); 
    } 
    }; 

    var setId = function (newId) { 
    myId = newId; 
    }; 

    // run 'constructor' 
    init(); 

    /* public methods */ 

    return { 
    getId: function() { 
     return myId; 
    }, 
    setId: function (newId) { 
     setId(newId); 
    }, 
    incrementId: function (inc) { 
     setId(myId + inc); 
    } 
    }; 
} 

// creating an instance of gizmo 

var myGizmo = gizmo(-2); 
console.log(myGizmo.getId()); // outputs 1 

myGizmo.setId(5); 
console.log(myGizmo.getId()); // outputs 5 

myGizmo.incrementId(2); 
console.log(myGizmo.getId()); /// outputs 7 

Bu iyi iş gibi görünüyor:

Bu bir nesne yapısı tipik bir yoldur. Bununla birlikte, bunu JSLint aracılığıyla çalıştırdığımda, bana iki özel işlevimin 'Implied Globals' olduğunu belirten bir hata veriyor.

Böyle değişkenlerle üstündeki benim fonksiyonları beyan etmektir ile gelebilir iyi:

function gizmo(id) { 

    /* private variables */ 

    var myId = id, 
     init, 
     setId; 

    /* private methods */ 

    init = function() { 
    if (myId < 1) { 
     setId(1); 
    } 
    }; 

    setId = function (newId) { 
    myId = newId; 
    }; 

    // run 'constructor' 
    init(); 

    /* public methods */ 

    return { 
    getId: function() { 
     return myId; 
    }, 
    setId: function (newId) { 
     setId(newId); 
    }, 
    incrementId: function (inc) { 
     setId(myId + inc); 
    } 
    }; 
} 
+2

Bu, tavsiye olarak çok fazla bir cevap değildir. JsLint hakkında çok fazla endişelenme. Sık sık çok sıkı buluyorum. Bunun yerine programlamaya odaklanın. Bu, başkalarının en iyi uygulamayı tartışmasına izin vereceğim dedi. – TNi

+0

Anlaşmalı. Çok fazla stres atmıyorum. Kodlarımı, burada ve internette öğrendiklerime dayanarak yapılandırabiliyorum. Son birkaç gün içinde JSLint ile uğraşıyorum ve diğer insanların hepsini ele almakla ilgileniyordum. –

+0

sorun, init ve işlevlerin sırasını. Nesneyi döndürmeden önce init hareket ettirir, geçecektir. Ayrıca init işlevine ihtiyacınız olduğunu düşünmüyorum. Belki sadece bir şeyleri ayırmak için kendi kendini yürüten ve anonim olarak. – galambalazs

cevap

1

JSLint'te bir hata olduğundan eminim. Henüz setId görmemiş, bu yüzden küresel olduğunu varsayar. Ama gerçekte, hiçbir farketmez, çünkü tüm var s, ECMAScript 5 10.5 uyarınca kaldırılır. Bu, ilk örneğiniz ve ikincinin aynı semantik olduğu anlamına gelir. İşlevdekinumaralı yerel bir değişken bildirimi hemen işlenir ve ilk olarak undefined değerine sahip olarak bağlanır. Ancak, işlev (örneğin, init) aslında çalıştığında, kapalı değer artık undefined'dur.

bu testi yapmak, setId başlangıçta tanımlanmamış olduğunu görüyoruz, ama asla bir küresel atıfta için:

function setId() 
{ 
    alert("Global setId"); 
} 
function f() 
{ 
    var init = function() 
    { 
    setId(); 
    } 
    alert(typeof(setId)); 
    init(); 
    var setId = function() 
    { 

    } 
} 

Bu tanımsız uyaracaktır, daha sonra TypeError hatası atmak.

+0

+1, Kaldırma hakkında bir şey bilmiyordum. Sadece her şeyi sırayla ilan etmek zorunda olduğunuzu farz ettim. – gradbot

+0

Çapraz tarayıcı çalışması için bunları sırayla bildirmelisiniz. – lawnsea

+0

@lawnsea, hangi tarayıcı farklı davranır ve nasıl? –

0

Ben jslint bilmem ama "javascript iyi parçalar" okuduktan sonra, Nesneleri her zaman açık olarak beyan ederim.

örn: Aslında yukarıdaki herhangi bir nesneyi ilan etmiyoruz

Mogwai={ 
    has_crazy_thoughts:True, 
    reacts_to_water:True, 
    name: 'Gizmo', 
    eat:function(food){ 
    // code 
    }, 
    become_gremlin:function(){ 
    // code 
    }, 
    cause_havoc:function(){ 
    // code 
    } 
} 

. Sadece bir işlev. İç işlevler Javascript'te gerçekten mevcut değil - Java gibi değil.

DÜZENLEME: Yukarıda belirtilen kitabı (bağlı olmadan) tavsiye ederim: http://oreilly.com/catalog/9780596517748 ... bize JSlint'i getiren Douglas Crockford tarafından yazılmıştır.

+1

Kitabın sahibiyim. Ve evet, güzel. Yukarıdaki örneğim özel değişkenler oluşturur ve kapanışları kullanarak çalışır, yani bu kitapta Crockford'un da bir şeyleri vardır. Örneğinizle, yalnızca nesne değişmezlerini kullanarak, özel değişkenler veya işlevler oluşturmanın hiçbir yolu yoktur. –

+0

Aslında bir nesneyi beyan ediyorsunuz. Nesnenin özelliklerine doldurulmuş bir nesnenin yanı sıra üç işlev, iki boole ve bir dize bildiriyorsunuz. – icktoofay

+0

Ayrıca, "True" ve "False" JavaScript'te küçük harflerdir. – icktoofay

3

JSLint, setId'nin init dosyasında başvurulan önce tanımlanmasını bekler.

Bu, JSLint'ten geçer.

function gizmo(id) { 

    /* private variables */ 

    var myId = id; 

    /* private methods */ 

    var setId = function (newId) { 
    myId = newId; 
    }; 

    var init = function() { 
    if (myId < 1) { 
     setId(1); 
    } 
    }; 

    // run 'constructor' 
    init(); 

    /* public methods */ 

    return { 
    getId: function() { 
     return myId; 
    }, 
    setId: function (newId) { 
     setId(newId); 
    }, 
    incrementId: function (inc) { 
     setId(myId + inc); 
    } 
    }; 
} 
+0

işlev setId() işlevini kullanarak tanımlamam fark etmez, JSLint'te aynı Implied Global hatasını alıyorum. –

+0

Sadece bunu JSLint üzerinden çalıştırdım ve geçti. Web sitelerinde deneyin. http://www.jslint.com/ – gradbot

+1

'setId' hiçbir zaman bir global anlamına gelir. Kaldırma nedeniyle, her zaman yerel değişkeni ifade eder. Bu yerel değişkenin değerinin başlangıçta tanımsız olduğu doğrudur, ancak bu init 'çağrıldığında tanımlandığı için alakasızdır. –

0

Ben ciddiye JavaScript programlanmış ettik, bu yüzden en iyi uygulama ayrıntılarına hafızam oldukça gitmiş beri uzun bir süre (birkaç yıl) olmuştur. Yaptığım şey geri döndü ve bilinçli bir karar vermene yardımcı olabilecek birkaç kaynak kazdı.

İlk olarak, nesnelerinizi oluşturma şekliniz, Module Pattern'u hatırlatıyor gibi görünüyor. Hatırladığım kadarıyla, bağlandığım makale bunun hakkında oldukça iyi bir okuma. İkincisi, belki de instantiate your objects'a farklı bir yol tercih edersiniz. Bu makale size biraz farklı bir şey kazandırıyor.

+0

Serin. Resig'in şu anki yazılarını okuyoruz. Teşekkürler. –

İlgili konular