Neden bir nesneymiş gibi diziye adlandırılmış özellikler ekleyebilirim?


105

Aşağıdaki iki farklı kod parçacığı bana eşdeğer görünüyor:

var myArray = Array();
myArray['A'] = "Athens";
myArray['B'] = "Berlin";

ve

var myObject = {'A': 'Athens', 'B':'Berlin'};

çünkü ikisi de aynı şekilde davranır ve ayrıca typeof(myArray) == typeof(myObjects)(her ikisi de 'nesne' verir).

Bu varyantlar arasında herhangi bir fark var mı?

Yanıtlar:


131

JavaScript'teki hemen hemen her şey bir nesnedir, bu nedenle bir Array nesnesini, üzerinde rastgele özellikler ayarlayarak "kötüye kullanabilirsiniz" . Bu zararlı kabul edilmelidir bile. Diziler sayısal olarak dizinlenmiş veriler içindir; sayısal olmayan anahtarlar için bir Nesne kullanın.

Sayısal olmayan anahtarların neden bir Diziye "uymadığına" dair daha somut bir örnek:

var myArray = Array();
myArray['A'] = "Athens";
myArray['B'] = "Berlin";

alert(myArray.length);

Bu, '2'yi göstermez, ancak' 0 '- etkili bir şekilde, diziye hiçbir öğe eklenmemiştir, yalnızca dizi nesnesine bazı yeni özellikler eklenmiştir.


4
myArray.length, dizideki son öğenin sayısal bir dizinini / anahtarını döndürür, ancak öğelerin gerçek sayısını döndürmez. Array nesnesinin özellikleri dizi değerleriyle aynı değil mi?
Dasha Salo

1
Array nesnesinin amaçlanan semantiğinin, onu normal bir nesne gibi ele alırsanız kötüye kullanıldığını göstermeye çalışıyordum. Bağlantılı makale yine de daha iyi bir iş çıkarıyor :)
Paul Dixon

13
Bir dahaki sefere birisi JavaScript'in geliştirmek için iyi bir dil olduğunu söylediğinde, ona bu örneği göstereceğim. Teşekkür ederim.
Olivier Pons

@Olivier, "böcek" dediğiniz şey harika bir "özellik" de olabilir. Sen içeriğini veya uzunluğunu etkilemeden ve nesnelerin onları sarmak zorunda kalmadan diziler bir ünvanı ve açıklama ekleyebilirsiniz title, descriptionve itemsözellikleri. Her şey, dili ne kadar iyi bildiğinize ve nasıl kullandığınıza bağlıdır.
tao

Dizilerde özel özellikleri kullanmak doğal olarak yanlış değildir. Yanlış olan şey, bir kez yaptıktan sonra dizi üyesi olarak hareket etmelerini beklemektir. Üyeler değil, dizi özellikleridir, dolayısıyla dizi yöntemlerinden etkilenmezler. Bu aslında yukarıdaki bağlantılı makalenin yazarı tarafından yorumlarda söylenir. Şimdi, adil olmak gerekirse, bir uygulama olarak buna karşı tavsiyede bulunacağım, çünkü muhtemelen kodunuzu kullanan insanların kafasını karıştıracaktır. Ya da yeni başlıyorlarsa, örneklerin gücüyle onları tehlikeli bir yola sokacaktır. Ancak JavaScript'in kötü olduğunu söyleyemem çünkü çoğunun beklemediği şeylere izin veriyor.
tao

14

JS'de diziler nesnelerdir, sadece biraz değiştirilmiştir (birkaç işlevle birlikte).

Gibi işlevler:

concat
every   
filer
forEach
join
indexOf
lastIndexOf
map
pop
push
reverse
shift
slice
some
sort
splice
toSource
toString
unshift
valueOf 

Listelenen tüm işlevlerin her JS uygulamasında yerleşik olduğunu düşünmesem de, anladınız. Diğer fark, farklı prototip olacaktır (bu, bu ekstra işlevler tarafından ima edilmektedir).
Rashack

6

Bana göre, önceki cevabımla beni fazla mecazi ve şifreli. Açıklama aşağıdaki gibidir.

Bir Array, Boolean, Date, Function, Number, RegExp, String örneği bir Object'tir ancak her türe özgü yöntemler ve özelliklerle geliştirilmiştir. Örneğin, bir dizinin önceden tanımlanmış bir lengthözelliği vardır, ancak genel nesneler yoktur.

javascript:alert([].length+'\n'+{}.length)

görüntüler

0
Tanımsız

İçsel olarak, FF Gecko yorumlayıcısı, dil yapılarını değerlendiren belirgin farklılıklar ile Diziler ve genel Nesneler arasında ayrım yapar.

javascript:
  ra=[  "one",   "two",   "three"]; ra.a=4;
  ob={0:"one", 1:"two", 2:"three"}; ob.a=4;
  alert(
    ra            +"\n\n"+
    ob            +"\n\n"+
    ra.toSource() +"\n\n"+
    ra.a          +"\t .toSource() forgot me! \n\n"+
    ra.length     +"\t and my length! \n\n"+
    ob.toSource());
  ps=""; for(i in ra)ps+=i+" "; alert(ps);  /* NB .length is missing! */
  ps=""; for(i in ob)ps+=i+" "; alert(ps);

görüntüleme

bir, iki, üç

[nesne Nesne]

["bir, iki, üç"]

4 .toSource () beni unuttu! 

3 ve boyum! 

({0: "bir", 1: "iki", 2: "üç", a: 4})

ve 0 1 2 ave 0 1 2 a.

Tüm nesnelerin işlev olduğu ifadesine gelince:

Bu ne sözdizimsel de anlam doğru gibi bir fonksiyonu olarak rasgele bir nesne örneği kullanmaktır 123()veya "abc"()veya []()veya {}()veya obj()burada objbaşka herhangi bir tip Functionrasgele bir nesne örneği değildir, bu yüzden Function. Ancak, bir nesne verilir objve 's tipi olarak Array, Boolean, Date, ..., nasıl ki objbir şekilde olması geliyor Array, Boolean, Date, ...? Bir nedir Array, Boolean, Date, ...?

javascript:
    alert([Array, Boolean, Date, Function, 
              Number, Object, RegExp, String] . join('\n\n') );

görüntüler

function Array() {
    [native code]
}

function Boolean() {
    [native code]
}

function Date() {
    [native code]
}

function Function() {
    [native code]
}

function Number() {
    [native code]
}

function Object() {
    [native code]
}

function RegExp() {
    [native code]
}

function String() {
    [native code]
}

Her durumda, belirsizlik olmadan, nesne türü bir functiontanım olarak ortaya çıkar , dolayısıyla tüm nesnelerin işlevler olduğu ifadesi ortaya çıkar! (Yanak dili, bir nesne örneğinin farklılığını kendi türününkiyle kasıtlı olarak gizlemem ve bulanıklaştırmamdır! Yine de bu, "biri olmadan diğerine sahip olamayacağınızı" gösterir, Nesne ve İşlev! örneğin aksine.)

Hem işlevsel hem de nesne paradigması, Mathve JSONve gibi JS yorumlayıcısının düşük seviyeli yerleşik ilkellerinin programlanması ve uygulanması için temel gibi görünmektedir true.

 javascript:alert([Math, JSON, true.toSource()].join("\n\n"));

görüntüler

[object Math]

[object JSON]

(new Boolean(true))

Javascript geliştirilirken, nesne merkezli bir programlama stili (OOP - Nesne Yönelimli Programlama stili - "s" benim kelime oyunumdur!) Revaçtaydı ve tercümana benzer şekilde daha fazla güvenilirlik sağlamak için Java ile vaftiz edildi . İşlevsel programlama teknikleri, Otomata, Özyinelemeli İşlevler, Biçimsel Diller vb. Kuramlarını inceleyen ve bu nedenle lezzetli olmayan daha soyut ve ezoterik incelemelere indirildi. Bununla birlikte, bu resmi düşüncelerin güçlü yönleri, özellikle FF'nin Gecko motorunda (yani. .toSource()) Uygulandığı haliyle Javascript'te açıkça görülmektedir .


İşlev için Nesne tanımı, bir yineleme ilişkisi olarak tanımlandığı için özellikle tatmin edicidir! kendi tanımı kullanılarak tanımlanmıştır!

function Function() { [native code] }
ve bir işlev bir Nesne olduğu için aynı duygu geçerlidir
function Object() { [native code] }.

Diğer tanımların çoğu, durağan bir uç değerde sessizleşir. Bununla birlikte, eval()özellikle güçlü bir ilkeldir ve bu nedenle, bir String aynı zamanda keyfi işlevselliği de katıştırabilir.

Yukarıda kullanılan yerel dilin nesne türünü ve örnek ayrımını gizlediğini tekrar unutmayın.


5

JavaScript'teki her şey, ilkel türlerin yanı sıra bir nesnedir.

Kod

var myArray = Array();

Array nesnesinin bir örneğini oluşturur

var myObject = {'A': 'Athens', 'B':'Berlin'};

Object nesnesinin bir örneğini oluşturur.

Aşağıdaki kodu deneyin

alert(myArray.constructor)
alert(myObject.constructor)

Dolayısıyla, farkın nesne yapıcı türünde olduğunu göreceksiniz.

Array nesnesinin örneği, Array prototipinin tüm özelliklerini ve yöntemlerini içerir.


2

Diziler ve JavaScript'teki diğer nesneler arasındaki fark. Diziler sihirli bir şekilde güncellenen uzunluk özelliğine sahipken, diziler dışındaki nesneler için böyle bir özelliği uygulamanın bir yolu yoktur.

var arrName = [];
arrName[5] = "test";
arrName.length; // <- 6

Dizi, sıralı dizine sahip şeyleri depolamak için kullanılır - geleneksel bir dizi, yığın veya sıra gibi kullanın. Nesne bir karmadır - onu farklı bir anahtarı olan veriler için kullanın.


2

Javascript'teki hemen hemen her şeye adlandırılmış özellikler ekleyebilirsiniz, ancak bu yapmanız gerektiği anlamına gelmez. Arrayjavascript'te, Objectbunun yerine ilişkilendirilebilir bir dizi kullanmak istiyorsanız, liste olarak kullanılmalıdır .

Bu Arrayözellikler yerine adlandırılmış özelliklere sahip bir kullanmayı gerçekten istiyorsanız Object, bir for...ofdöngüde erişilebilir olmayacağına ve JSON onu iletmek için kodlarken beklenmedik sonuçlar alabileceğinizi unutmayın. Sayısal olmayan tüm dizinlerin yok sayıldığı aşağıdaki örneğe bakın :

let arr = [];
let obj = {};

arr['name'] = 'John';
obj['name'] = 'John';

console.log(arr);    // will output [name: "John"]
console.log(obj);    // will output {name: "John"}

JSON.stringify(arr); // will return [] <- not what you expected
JSON.stringify(obj); // will return {"name":"John"}

-1

{}-Notation kodu daha güzel yapmak için sadece sözdizimsel şeker ;-)

JavaScript, işlevlerin inşası gibi birçok benzer yapıya sahiptir; burada function (),

var Func = new Function("<params>", "<code>");

3
İşlev yapıcısı, işlev değişmezinin eşanlamlısı DEĞİLDİR . Yapıcı global iken literal sözcüksel olarak kapsamlıdır. {}gerçek nesne gösterimi, []değişmez dizidir, cevabınızın amacının ne olduğundan emin değilim.
Juan Mendes

Ayrıca, bildirilen işlevler herhangi bir kod yürütülmeden önce kullanılabilir, İşlev yapıcısı kullanılarak yapılan atamalar, onları oluşturan kod çalıştırılıncaya kadar kullanılamaz.
RobG
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.