Javascript nesnelerinin dinamik oluşturulması. Yeni bir nesnenin oluşturulması. Bir yapıcı işlevi kullanma

  • 14.05.2019

JavaScript, basit bir nesne tabanlı paradigma üzerinde tasarlanmıştır. Bir nesne, bir özellikler topluluğudur ve bir özellik, bir ad (veya anahtar) ve bir değer. Bir özelliğin değeri bir işlev olabilir, bu durumda özellik bir yöntem olarak bilinir. Tarayıcıda önceden tanımlanmış nesnelere ek olarak kendi nesnelerinizi de tanımlayabilirsiniz. Bu bölüm nesnelerin, özelliklerin, işlevlerin nasıl kullanılacağını açıklar. , ve yöntemler ve kendi nesnelerinizi nasıl oluşturacağınız.

Nesneye genel bakış

JavaScript'teki nesneler, diğer birçok programlama dilinde olduğu gibi, gerçek hayattaki nesnelerle karşılaştırılabilir. JavaScript'teki nesne kavramı, gerçek hayattaki somut nesnelerle anlaşılabilir.

JavaScript'te bir nesne, özellikleri ve türü olan bağımsız bir varlıktır. Örneğin bir bardakla karşılaştırın. Bir fincan, özellikleri olan bir nesnedir. Bir bardağın rengi, tasarımı, ağırlığı, yapıldığı malzeme vb. Aynı şekilde, JavaScript nesneleri de özelliklerini tanımlayan özelliklere sahip olabilir.

Nesneler ve özellikler

Bir JavaScript nesnesi, kendisiyle ilişkilendirilmiş özelliklere sahiptir. Bir nesnenin özelliği, nesneye eklenen bir değişken olarak açıklanabilir. Nesne özellikleri, nesnelere ek dışında, temel olarak sıradan JavaScript değişkenleriyle aynıdır. Bir nesnenin özellikleri, nesnenin özelliklerini tanımlar. Basit bir nokta gösterimi ile bir nesnenin özelliklerine erişirsiniz:

NesneAdı.özellikAdı

Tüm JavaScript değişkenleri gibi, hem nesne adı (normal bir değişken olabilir) hem de özellik adı büyük/küçük harfe duyarlıdır. Bir özelliği, ona bir değer atayarak tanımlayabilirsiniz. Örneğin, myCar adında bir nesne oluşturalım ve ona make , model ve year adlı özellikleri aşağıdaki gibi verelim:

Var myCar = new Object(); myCar.make = "Ford"; myCar.model = "Mustang"; arabam.yıl = 1969; arabam.renk; // Tanımsız

JavaScript nesnelerinin özelliklerine ayrıca bir parantez gösterimi kullanılarak erişilebilir veya ayarlanabilir (daha fazla ayrıntı için özellik erişimcilerine bakın). Nesneler bazen denir ilişkili diziler, çünkü her özellik, ona erişmek için kullanılabilecek bir dize değeriyle ilişkilendirilir. Örneğin, myCar nesnesinin özelliklerine aşağıdaki gibi erişebilirsiniz:

MyCar["make"] = "Ford"; myCar["model"] = "Mustang"; arabam["yıl"] = 1969;

Bir nesne özelliği adı, herhangi bir geçerli JavaScript dizesi veya boş dize de dahil olmak üzere bir dizeye dönüştürülebilen herhangi bir şey olabilir. Ancak, geçerli bir JavaScript tanımlayıcısı olmayan herhangi bir özellik adına (örneğin, boşluk veya kısa çizgi içeren veya bir sayı ile başlayan bir özellik adı) yalnızca köşeli parantez gösterimi kullanılarak erişilebilir. Bu gösterim, özellik adlarının dinamik olarak belirleneceği durumlarda da (özellik adı çalışma zamanına kadar belirlenmediğinde) çok kullanışlıdır. Örnekler aşağıdaki gibidir:

// tek seferde dört değişken oluşturulur ve atanır, // virgülle ayrılır var myObj = new Object(), str = "myString", Rand = Math.random(), obj = new Object(); myObj.type = "nokta sözdizimi"; myObj["oluşturulma tarihi"] = "Boşluklu dize"; myObj = "dize değeri"; myObj = "Rastgele Sayı"; myObj = "Nesne"; myObj[""] = "Boş bir dize bile"; konsol günlüğü(myObj);

JavaScript nesne özellik adları (anahtarlar) yalnızca dizeler veya Semboller olabileceğinden (bir noktada, sınıf alanları önerisi olarak özel adlar da eklenecektir) olduğundan, köşeli parantez gösterimindeki tüm anahtarların Sembol olmadıkça dizeye dönüştürüldüğünü unutmayın. ilerler, ancak bunları formla kullanmazsınız). Örneğin, yukarıdaki kodda, obj anahtarı myObj öğesine eklendiğinde, JavaScript obj.toString() yöntemini çağırır ve bu sonuç dizesini yeni anahtar olarak kullanır.

Bir değişkende depolanan bir dize değeri kullanarak da özelliklere erişebilirsiniz:

var propertyName = "yap"; myCar = "Ford"; propertyName = "model"; myCar = "Mustafa";

Bir yapıcı işlevi kullanma

Alternatif olarak, şu iki adımla bir nesne oluşturabilirsiniz:

  1. Bir yapıcı işlevi yazarak nesne türünü tanımlayın. Büyük bir ilk harf kullanmak için iyi bir nedenle güçlü bir kural vardır.
  2. new ile nesnenin bir örneğini oluşturun.

Bir nesne türü tanımlamak için, nesne türü için adını, özelliklerini ve yöntemlerini belirten bir işlev oluşturun. Örneğin, arabalar için bir nesne türü oluşturmak istediğinizi varsayalım. Bu tür bir nesnenin adının Car olmasını istiyorsunuz ve onun marka, model ve yıl özelliklerine sahip olmasını istiyorsunuz. Bunu yapmak için aşağıdaki işlevi yazarsınız:

Fonksiyon Araba(marka, model, yıl) ( bu.make = marka; bu.model = model; bu.yıl = yıl; )

İşleve iletilen değerlere dayalı olarak nesnenin özelliklerine değer atamak için bunun kullanımına dikkat edin.

Şimdi mycar adlı bir nesneyi aşağıdaki gibi oluşturabilirsiniz:

Var mycar = new Car("Kartal", "Talon TSi", 1993);

Bu ifade mycar'ı oluşturur ve ona özellikleri için belirtilen değerleri atar. O zaman mycar.make'in değeri "Eagle" dizesidir, mycar.year 1993 tamsayıdır ve bu böyle devam eder.

new öğesini çağırarak istediğiniz sayıda Car nesnesi oluşturabilirsiniz. Örneğin,

Varkenscar = yeni Araba("Nissan", "300ZX", 1992); var vpgscar = new Car("Mazda", "Miata", 1990);

Bir nesne, kendisi başka bir nesne olan bir özelliğe sahip olabilir. Örneğin, kişi adlı bir nesneyi aşağıdaki gibi tanımladığınızı varsayalım:

Fonksiyon Kişi(isim, yaş, cinsiyet) ( this.name = isim; this.age = yaş; this.sex = cinsiyet; )

ve ardından iki yeni kişi nesnesini aşağıdaki gibi somutlaştırın:

Var rand = new Kişi("Rand McKinnon", 33, "M"); var ken = new Kişi("Ken Jones", 39, "M");

Ardından, bir kişi nesnesini alan bir sahip özelliği eklemek için Araba tanımını aşağıdaki gibi yeniden yazabilirsiniz:

Fonksiyon Araba(marka, model, yıl, sahip) ( bu.marke = marka; bu.model = model; bu.yıl = yıl; bu.sahip = sahip; )

Yeni nesneleri somutlaştırmak için aşağıdakileri kullanırsınız:

Var car1 = new Car("Kartal", "Talon TSi", 1993, rand); var car2 = new Car("Nissan", "300ZX", 1992, ken);

Yeni nesneleri oluştururken bir hazır bilgi dizesi veya tamsayı değeri iletmek yerine, yukarıdaki ifadelerin sahipler için argümanlar olarak rand ve ken nesnelerini ilettiğine dikkat edin. Daha sonra car2'nin sahibinin adını öğrenmek isterseniz aşağıdaki özelliğe erişebilirsiniz:

araba2.sahibi.adı

Önceden tanımlanmış bir nesneye her zaman bir özellik ekleyebileceğinizi unutmayın. Örneğin, açıklamada

araba1.color = "siyah";

car1'e bir özellik rengi ekler ve ona "siyah" değerini atar. Ancak, bu diğer nesneleri etkilemez. Yeni özelliği aynı türdeki tüm nesnelere eklemek için, özelliği Car nesne türünün tanımına eklemeniz gerekir.

Object.create yöntemini kullanma

Ayrıca bakınız

  • Daha derine inmek için javaScript'in nesne modelinin ayrıntılarını okuyun.
  • ECMAScript 2015 sınıfları (nesne oluşturmanın yeni bir yolu) hakkında bilgi edinmek için JavaScript sınıfları bölümünü okuyun.

nesneler

Nesne, JavaScript dilinde temel bir veri türüdür. Bir obje bileşik bir değerdir: bir dizi değeri (basit değerler veya diğer nesneler) birleştirir ve bu değerleri ada göre saklamanıza ve almanıza olanak tanır.

Bir nesne, her biri bir ad ve değere sahip sıralanmamış bir özellikler topluluğudur. Özellik adları dizelerdir, dolayısıyla nesnelerin dizeleri değerlerle eşlediğini söyleyebilirsiniz. Dizelerin değerlere bu şekilde eşlenmesi farklı şekilde adlandırılabilir: "karma", "sözlük" veya "ilişkisel dizi" gibi temel bir veri yapısına zaten aşina olabilirsiniz. Bununla birlikte, bir nesne, dizelerden değerlere bir eşlemeden daha fazlasıdır.

JavaScript nesneleri, kendi özelliklerine ek olarak, "prototipler" olarak bilinen diğer nesnelerden de özellikler devralabilir. Nesne yöntemleri, miras alınan özelliklerin tipik temsilcileridir ve " prototip kalıtımı" bir anahtar özellik JavaScript dili.

JavaScript'teki nesneler dinamiktir - genellikle özellikler eklemenize ve kaldırmanıza izin verir - ancak statik tip sistemli programlama dillerinde bulunan statik nesneleri ve "yapıları" taklit etmek için de kullanılabilirler. Ayrıca (nesnelerin dizeleri değerlere eşlemesi dışında) dize kümelerini temsil etmek için kullanılabilirler.

JavaScript'te dize, sayı, true, false, null veya undefined olmayan herhangi bir değer bir nesnedir. Ve nesne olmayan dizgiler, sayılar ve booleler bile değişmez nesneler gibi davranabilir (String, Number, vb. sarmalayıcı nesnelere sahiptir).

Nesneler değiştirilebilir değerlerdir ve değere göre değil referansa göre çalıştırılır. x değişkeni bir nesneye atıfta bulunuyorsa ve deyimi var y = x; , aynı nesneye yapılan bir başvuru, bir kopyası değil, y değişkenine yazılacaktır. y değişkeni kullanılarak nesnede yapılan herhangi bir değişiklik, x değişkenine de yansıtılacaktır.

Bir özelliğin bir adı ve bir değeri vardır. Özellik adı, boş dize de dahil olmak üzere herhangi bir dize olabilir, ancak bir nesnenin aynı ada sahip iki özelliği olamaz. Özellik değeri, JavaScript dilinde izin verilen herhangi bir değer veya (ECMAScript 5'te) bir okuma veya yazma işlevi (veya her ikisi) olabilir.

Adlara ve değerlere ek olarak, her özelliğin kendisiyle ilişkili bir değerler kümesi vardır. özellik özellikleri :

    Bağlanmak yazılabilir bir özellik değerinin yazılabilir olup olmadığını belirler.

    Bağlanmak sayılabilir for/in döngüsünde numaralandırma için bir özellik adının kullanılabilir olup olmadığını belirler.

    Bağlanmak yapılandırılabilirözelleştirme olasılığını belirler, yani. bir özelliği silmek ve niteliklerini değiştirmek.

ECMAScript 5 standardının ortaya çıkmasından önce, nesnelerdeki tüm özellikler program tarafından oluşturulan, yazılabilir, numaralandırılabilir ve yapılandırılabilir. ECMAScript 5, mülklerinizin özniteliklerini özelleştirme yeteneği sağlar.

Özelliklere ek olarak, her nesnenin üç nesne niteliği :

    Bağlanmak sınıf nesnenin sınıfının adını içeren bir dize içerir ve nesnenin türünü belirtir.

    bayrak genişletilebilir(ECMAScript 5'te) bir nesneye yeni özellikler ekleme yeteneğini gösterir.

Son olarak, aşağıda, JavaScript nesnelerinin üç geniş kategorisini ve iki tür özelliği ayırt etmemize yardımcı olacak bazı terimlerin açıklaması yer almaktadır:

Temel Dil Nesnesi

ECMAScript belirtimi tarafından tanımlanan bir nesne veya nesne sınıfıdır. Diziler, işlevler, tarihler ve düzenli ifadeler (örneğin) temel dil nesneleridir.

çalışma zamanı nesnesi

Bu, JavaScript yorumlayıcısının gömülü olduğu çalışma zamanı (bir web tarayıcısı gibi) tarafından tanımlanan bir nesnedir. İstemci tarafı JavaScript'te bir web sayfasının yapısını temsil eden HTMLElement nesneleri, çalışma zamanı nesneleridir. Çalışma zamanı nesneleri, örneğin çalışma zamanı, normal JavaScript ana bilgisayar dili İşlev nesneleri olan yöntemleri tanımladığında, ana bilgisayar dili nesneleri de olabilir.

Özel Nesne

JavaScript kodunun yürütülmesi sonucunda oluşturulan herhangi bir nesne.

Kendi mülkü

Doğrudan verilen nesne üzerinde tanımlanan bir özelliktir.

devralınan mülk

Bu, nesnenin prototipi tarafından tanımlanan bir özelliktir.

nesneler oluşturma

Nesneler, nesne değişmezleri, yeni anahtar sözcük ve (ECMAScript 5'te) işlevler kullanılarak oluşturulabilir. Object.create().

Nesne Değişmezleri

Bir nesne yaratmanın en kolay yolu, programa bir nesne değişmezi eklemektir. Bir nesne değişmezi, küme parantezleri içine alınmış virgülle ayrılmış bir özellikler listesidir (ad/değer çiftleri). Özellik adı bir tanımlayıcı veya bir dize değişmezi olabilir (boş bir dizeye izin verilir). Bir özelliğin değeri, JavaScript'te izin verilen herhangi bir ifade olabilir - ifadenin değeri (basit bir değer veya bir nesne olabilir), özelliğin değeri olur.

Aşağıda bazı nesne oluşturma örnekleri verilmiştir:

var boş = (); // Özelliği olmayan nesne var point = ( x:0, y:0 ); // İki özellik var point2 = ( x:point.x, y:point.y+1 ); // Daha karmaşık değerler var site = ("url site": "www..NET Framework", // ve kısa çizgiler, bu nedenle tırnak işaretleri kullanın yazar: ( // Bu özelliğin değeri firstname: "Alexandr", / / nesne Soyadına dikkat edin: "Frolov" // bu özelliklerin isimleri tırnak işaretleri olmadan. ) );

ECMAScript 5'te (ve ECMAScript 3'ün bazı uygulamalarında) tırnak işaretleri olmadan özellik adları olarak ayrılmış sözcüklerin kullanılmasına izin verilir. Ancak genel olarak, ayrılmış sözcüklerle eşleşen özellik adları ECMA-Script 3'te tırnak işaretleri içine alınmalıdır. ECMAScript 5'te, bir nesne değişmezindeki son özelliği izleyen son virgül yok sayılır. ECMAScript 3'ün çoğu uygulaması, sondaki virgülleri de yok sayar, ancak IE bunların varlığını bir hata olarak yorumlar.

Bir nesne değişmez değeri, bu ifade her değerlendirildiğinde yeni bir nesne oluşturan ve başlatan bir ifadedir. Her bir özelliğin değeri, değişmezin değeri değerlendirildiğinde yeniden değerlendirilir. Bu, tek bir nesne değişmezinden, o değişmez bir döngünün veya tekrar tekrar çağrılacak bir işlevin gövdesine yerleştirilirse birçok yeni nesnenin oluşturulabileceği ve bu nesnelerin özelliklerinin değerlerinin her birinden farklı olabileceği anlamına gelir. diğer.

Yeni operatörle nesneler oluşturma

Yeni operatör, yeni bir nesne oluşturur ve başlatır. Bu operatörün ardından işlevin adı gelmelidir. Bu şekilde kullanılan bir işleve yapıcı denir ve yeni oluşturulan bir nesneyi başlatmak için kullanılır. Temel JavaScript, temel dil nesneleri oluşturmak için birçok yerleşik oluşturucu içerir. Örneğin:

Varo = yeni Nesne(); // Yeni bir boş nesne oluşturun: () ile aynı var a = new Array(); // Boş bir dizi oluşturun: var d = new Date() ile aynı; // Geçerli saati temsil eden bir Date nesnesi oluşturun var r = new RegExp("js"); // Kalıp eşleştirme işlemleri için bir RegExp nesnesi oluşturun

Bu yerleşik kuruculara ek olarak, yeni oluşturulan nesneleri başlatmak için kendi kurucu işlevlerinizi tanımlamanız mümkündür. Bunun nasıl yapıldığı bir sonraki makalede anlatılmaktadır.

Object.create()

ECMAScript 5 standardı, yeni bir nesne oluşturan ve ilk argümanını o nesnenin prototipi olarak kullanan Object.create() yöntemini tanımlar. Ek olarak, Object.create(), yeni nesnenin özelliklerini tanımlayan isteğe bağlı ikinci bir argüman alabilir.

Object.create() statik bir işlevdir, bazılarına göre olarak adlandırılan bir yöntem değil. belirli nesne. Bu işlevi çağırmak için, istediğiniz prototip nesnesini iletmeniz yeterlidir:

// obj, x ve y özelliklerini miras alır var obj = Object.create((x:1, y:2));

Prototipi olmayan bir nesne oluşturmak için null iletebilirsiniz, ancak bu durumda yeni oluşturulan nesne, toString() gibi herhangi bir özelliği veya temel yöntemi devralmaz (bu, bu nesnenin ifadelerde kullanılamayacağı anlamına gelir). + operatörü):

// obj2 herhangi bir özelliği veya yöntemi miras almaz var obj2 = Object.create(null);

Programın sıradan bir boş nesne (örneğin, bir değişmez () veya yeni Object() ifadesi tarafından döndürülen) oluşturması gerekiyorsa, ilk argüman olarak Object.prototype iletin:

// obj3, () veya yeni Object() ile // oluşturulan bir nesne gibidir var obj3 = Object.create(Object.prototype);

Rastgele prototiplerle yeni nesneler yaratma yeteneği (diğer bir deyişle: herhangi bir nesneden "miras" yaratma yeteneği), aşağıdaki örnekte gösterilen işlev kullanılarak eylemi ECMAScript 3'te taklit edilebilecek güçlü bir araçtır:

// inherit(), p prototip nesnesinin özelliklerini devralan // yeni yaratılmış bir nesne döndürür. Tanımlanmışsa, ECMAScript 5 //'deki Object.create() işlevini kullanır, aksi takdirde eski numara kullanılır. function inherit(p) ( if (p == null) throw TypeError(); // p boş olamaz if (Object.create) // Object.create() tanımlanmışsa... Object.create(p) döndür ; // onu kullan var t = typeof p; // Aksi takdirde türü bulun ve test edin if (t !== "object" && t !== "function") throw TypeError(); function f() () ; // Boş bir kurucu tanımlayın f.prototype = p; // Prototip özelliğini // nesneye bir referans olarak ayarlayın p.döndür yeni f(); // f() öğesini kullanarak // bir "alt öğe" oluşturun p nesnesi.)

Bir sonraki makalede yapıcıları tanıdıktan sonra inherit() işlevinin uygulanması daha anlamlı olacaktır. Şimdilik, bunu argümandaki nesnenin özelliklerini miras alan yeni bir nesne döndürmek olarak düşünün. inherit() işlevinin Object.create() işlevinin tam yerine geçmediğine dikkat edin: nesnelerin prototip olmadan oluşturulmasına izin vermez ve Object.create()'in yaptığı gibi isteğe bağlı ikinci bir argüman almaz.

Özellikleri alma ve değiştirme

Nokta (.) ve köşeli parantez () operatörlerini kullanarak bir özelliğin değerini alabilirsiniz. Operatörün solunda bir nesne döndüren bir ifade olmalıdır. Nokta operatörünü kullanırken, sağda özellik adıyla eşleşen basit bir tanımlayıcı olmalıdır. Köşeli parantezler kullanılırken, parantezler, istenen özelliğin adını içeren bir dize döndüren bir ifadenin içine alınmalıdır:

// Basit nesne var user = ( login:"kot86", name:"Alexandr", age:26 ); var login = user.login; // Kullanıcı nesnesinin "login" özelliğini alın var name = user.name; // Kullanıcı nesnesinin "name" özelliğini alın var age = user["age"]; // Kullanıcı nesnesinin "age" özelliğini alın

Yeni bir özellik oluşturmak veya mevcut bir özelliğin değerini değiştirmek için özellik değeri okuma işlemlerinde olduğu gibi nokta operatörleri ve köşeli parantezler de kullanılır, ancak ifadenin kendisi atama operatörünün soluna yerleştirilir:

Kullanıcı yaşı = 28; // "age" özelliğinin değerini değiştirin user["login"] = "kot84"; // "login" özelliğinin değerini değiştirin user["surname"] = "Frolov"; // Yeni bir özellik "soyadı" oluştur

ECMAScript 3'te, bir noktanın ardından gelen tanımlayıcı ayrılmış bir kelime olamaz: o.for veya o.class özellik çağrısı yazamazsınız çünkü for bir anahtar kelimedir ve sınıf gelecekte kullanılmak üzere ayrılmış bir kelimedir.

Bir nesnenin, adları ayrılmış sözcüklerle eşleşen özellikleri varsa, bunlara erişmek için o["for"] ve o["class"] köşeli parantez gösterimini kullanmanız gerekir. ECMAScript 5 standardı bu gereksinimi hafifletir (bazı ECMAScript 3 uygulamalarında zaten yapıldığı gibi) ve kullanımına izin verir. Ayrılmış kelimeler nokta operatöründen sonra.

prototipler

Her JavaScript nesnesinin kendisiyle ilişkilendirilmiş ikinci bir nesnesi (veya boş, ancak çok daha az sıklıkla) vardır. Bu ikinci nesneye prototip denir ve ilk nesne, özelliklerini prototipten devralır.

Nesne değişmezleri ile oluşturulan tüm nesneler, aşağıdaki gibi bir JavaScript programında başvurulabilecek aynı prototip nesnesine sahiptir: Object.prototype .

new anahtar sözcüğü ve bir yapıcı çağrısı ile oluşturulan nesneler, prototip olarak yapıcı işlevinin prototip özelliğinin değerine sahiptir. Bu nedenle, new Object() ifadesi tarafından oluşturulan nesne, Object.prototype nesnesinin özelliklerini, sanki bir hazır bilgi ile oluşturulmuş gibi devralır. kıvırcık parantezler(). Benzer şekilde, new Array() tarafından oluşturulan nesnenin prototipi Array.prototype'dir ve new Date() tarafından oluşturulan nesnenin prototipi Date.prototype'dir.

Object.prototype, prototipi olmayan birkaç nesneden biridir: kalıtsal özellikleri yoktur. Diğer prototip nesneler, kendi prototiplerine sahip sıradan nesnelerdir.

Tüm yerleşik oluşturucular (ve çoğu kullanıcı tanımlı oluşturucu), Object.prototype öğesinden devralır. Örneğin, Date.prototype, özellikleri Object.prototype öğesinden devralır, dolayısıyla new Date() tarafından oluşturulan Date nesnesi, özellikleri Date.prototype ve Object.prototype olmak üzere her iki prototipten devralır. Böyle bir ilgili prototip nesne dizisine prototip zinciri denir.

Miras

JavaScript'teki nesnelerin birçok "kendi özelliği" vardır ve ayrıca prototip nesnesinden birçok özelliği devralabilir. Bunu anlamak için, mülklere erişim mekanizmasını dikkatlice incelemeniz gerekir. Bu bölümdeki örnekler, belirli prototiplere sahip nesneler oluşturmak için yukarıda gösterilen inherit() işlevini kullanır.

Programın obj nesnesinin x özelliğine eriştiğini varsayalım. Obj'nin bu ada sahip kendi özelliği yoksa, nesnenin prototipinde x özelliği aranmaya çalışılır. Prototip nesnesinin bu ada sahip kendi özelliği yoksa, ancak kendi prototipi varsa, prototipin prototipinde özellik bulunmaya çalışılır. Bu, x özelliği bulunana veya prototipi olmayan bir nesneye ulaşılana kadar devam eder. Gördüğünüz gibi, nesnenin prototip niteliği, özelliklerin devralındığı nesnelerin bir zincirini veya bağlantılı listesini oluşturur.

var nesne = (); // obj, nesne yöntemlerini devralır Object.prototype obj.x = 1; // ve kendi x özelliğine sahiptir. var p = devral(nesne); // p, obj ve Object.prototype özelliklerini miras alır p.y = 2; // ve kendi y özelliğine sahiptir. varq = devral(p); // q, p, obj ve Object.prototype nesnelerinin özelliklerini miras alır q.z = 3; // ve kendi z özelliğine sahiptir. var s = q.toString(); // toString, Object.prototype'dan miras alır var d = q.x + q.y // Sonuç 3: x ve y, obj ve p'den miras alınır

Şimdi programın obj'nin x özelliğine bir değer atadığını varsayalım. Obj zaten x adında kendi özelliğine (kalıtsal değil) sahipse, atama işlemi mevcut özelliğin değerini değiştirecektir. Aksi takdirde, obj nesnesinde x adında yeni bir özellik oluşturulacaktır. Obj önceden miras alınan özellik x ise, devralınan özellik şimdi aynı adı taşıyan yeni oluşturulan kendi özelliği tarafından gizlenecektir.

Özellik atama işlemi, atamanın geçerli olduğundan emin olmak için prototip zincirinde bu özelliğin varlığını kontrol edecektir. Örneğin, nesne nesnesi x salt okunur özelliğini devralırsa, atama başarısız olur. Ancak, atama geçerliyse, bir özellik her zaman orijinal nesnede oluşturulur veya değiştirilir ve asla prototip zincirinde olmaz. gerçeği kalıtım mekanizması özellikleri okurken çalışır, ancak yeni değerler yazarken çalışmaz, JavaScript dilinin önemli bir özelliğidir çünkü devralınan özellikleri seçici olarak geçersiz kılmanıza olanak tanır:

Var unitcircle = ( r:1 ); // Özelliğin miras alındığı nesne var c = inherit(unitcircle); // c, r c.x = 1 özelliğini devralır; c.y = 1; // c kendine ait iki özelliği tanımlar c.r = 2; // c devralınan özelliği geçersiz kılar console.log(unitcircle.r); // => 1: prototip nesnesi değişmedi

Özellik atama işlemi başarısız olduğunda veya orijinal nesnenin özelliğinin oluşturulması/değiştirilmesiyle sonuçlandığında bu kuralın bir istisnası vardır. Obj nesnesi x özelliğini miras alırsa ve bu özelliğe erişim erişimci yöntemlerle gerçekleştirilirse, nesne nesnesinde yeni bir x özelliği oluşturmak yerine yeni değeri ayarlama yöntemi çağrılır. Ancak, yazarın özelliğin tanımlandığı prototipte değil, nesne nesnesinde çağrıldığını unutmayın, bu nedenle yazar herhangi bir özellik tanımlarsa, bunlar nesne nesnesinde oluşturulur ve prototip zinciri yine değişmeden kalır.

Mülk Erişim Hataları

Özellik erişim ifadeleri her zaman bir özelliğin değerini döndürmez veya değiştirmez. Bu bölüm, bir özellik üzerinde okuma veya yazma işlemlerinin başarısız olduğu durumları açıklar.

Var olmayan bir özelliğe erişme girişimi hata olarak değerlendirilmez. x özelliği, nesne nesnesinin kendi veya devralınan özellikleri arasında bulunmazsa, nesne.x özelliğine erişim ifadesi tanımsız değerini döndürür.

Ancak, var olmayan bir nesnenin özelliğine erişme girişimi bir hata olarak kabul edilir. Boş ve tanımsız değerlerin hiçbir özelliği yoktur ve bu değerlerin özelliklerine erişme girişimleri hata olarak kabul edilir:

// Basit nesne var user = ( login:"kot86", name:"Alexandr", age:26 ); var a = user.password; // tanımsız: özellik yok // TypeError istisnası atar. // tanımsız değerin uzunluk özelliği yok var len = user.password.length;

user ve user.password'ün nesne olduğundan (veya nesneler gibi davrandığından) emin değilseniz, bir istisna oluşturabileceğinden user.password.length ifadesini kullanamazsınız. Aşağıda, bu tür bir istisnaya karşı koruma sağlamanın iki yolu gösterilmektedir:

// Daha açıklayıcı ve anlaşılır bir yol var len = undefined; if (user) ( if (user.password) len = user.password.length; ) // password özelliğinin değerinin uzunluğunu almak // için JavaScript'e daha kısa ve daha fazla alternatif var len = user && user.password && user.password.length ;

Bir özelliğin değerini başka değerlere ayarlama girişimleri her zaman başarılı olmaz: bazı özellikler salt okunurdur ve değerlerinin değiştirilmesine izin vermez. Ayrıca bazı nesneler onlara yeni özellikler eklemenize izin vermez. Bununla birlikte, en ilginç şey, bu tür başarısızlıkların, kural olarak, bir istisna atılmasına neden olmamasıdır:

// Yerleşik kurucuların prototip özellikleri salt okunurdur Object.prototype = 0; // Atama bir istisna atmaz; // Object.prototype değeri değişmeyecek

Bu tarihsel JavaScript hatası, ECMAScript 5 standardı tarafından tanımlanan katı modda düzeltildi. başarısız girişimler bir özelliğin değerini katı modda değiştirmek, TypeError istisnasına neden olur.

Bir atama işlemini gerçekleştirme girişiminin ne zaman başarılı ve ne zaman başarısız olduğunu belirleme kuralları basit ve anlaşılırdır, ancak yeterince özlü bir şekilde ifade etmek zordur. Obj öğesinin p özelliğine bir değer atama girişimi aşağıdaki durumlarda başarısız olur:

    Obj nesnesinin kendi salt okunur özelliği p vardır: salt okunur özelliğin değerini değiştiremezsiniz. (Ancak, salt okunur özel özelliklerin değerlerini değiştirmenize izin veren bir istisna olan defineProperty() yöntemine dikkat edin.)

    Obj nesnesi, devralınan salt okunur bir özelliğe sahiptir p: devralınan salt okunur özellikler, aynı ada sahip kendi özellikleri tarafından geçersiz kılınamaz.

    obj nesnesinin kendi p özelliği yoktur; obj nesnesi erişimci yöntemlerle p özelliğini devralmaz ve obj nesnesinin genişletilebilir özniteliği false olarak ayarlanır. p özelliği obj nesnesinde mevcut değilse ve bunun için herhangi bir ayarlayıcı tanımlanmadıysa, atama işlemi p özelliğini obj nesnesine eklemeye çalışacaktır. Ancak obj nesnesi genişletilebilir olmadığından, ona yeni bir özellik ekleme girişimi başarısız olacaktır.

Özellikleri kaldırma

Şebeke silmek bir nesneden bir özelliği kaldırır. Tek işleneni bir özellik erişim ifadesi olmalıdır. Şaşırtıcı görünebilir, ancak silme operatörü özelliğin değerini etkilemez - özelliğin kendisinde çalışır:

// Basit nesne var user = ( login:"kot86", name:"Alexandr", age:26 ); user.login'i silin; // Artık kullanıcı nesnesinin bir oturum açma silme özelliği yok user["name"]; // Artık kullanıcı nesnesinin bir name özelliği yok

Silme operatörü yalnızca kendi özelliklerini siler ve devralınanları silmez. (Devralınan bir özelliği silmek için, onu tanımlandığı prototip nesnesinde silmeniz gerekir. Bu işlem, bu prototipi devralan tüm nesneleri etkiler.)

Özellik başarıyla silindiyse veya silme işlemi nesneyi değiştirmediyse (örneğin, var olmayan bir özelliği silme girişiminde bulunulduysa) silme ifadesi true değerini döndürür. Bu operatöre özellik erişim ifadesi olmayan bir ifade iletildiğinde de silme ifadesi true değerini döndürür:

nesne = (x:1); // obj'nin kendi x özelliği vardır ve toString'i devralır delete obj.x; // x'i sil ve gerçek sil obj.x'i döndür; // Hiçbir şey yapmayın (x mevcut değil) ve true değerini döndürün delete obj.toString; // Hiçbir şey yapmayın (toString özel bir mülk değildir) ve true değerini döndürün delete 1; // Anlamsız, ancak true değerini döndürür

silme operatörü özel olmayan özellikleri kaldırmaz, öznitelik yapılandırılabilir hangisi yanlış. (Ancak, genişletilemeyen nesnelerin yapılandırılabilir özelliklerini kaldırabilir.) Yapılandırılamaz özellikler, yerleşik nesne özelliklerinin yanı sıra değişken ve işlev bildirim deyimleri kullanılarak oluşturulan genel nesne özellikleridir. Katı modda yapılandırılamayan bir özelliği silmeye çalışmak, TypeError istisnası oluşturur. Kesin olmayan modda (ve ECMAScript 3 uygulamalarında), silme operatörü bu gibi durumlarda basitçe false döndürür:

Object.prototype'ı silin; // Silme mümkün değil - yapılandırılamaz özellik var x = 1; // Global bir değişken bildiriliyor delete this.x; // Bu özellik silinemez fonksiyon f() () // Global fonksiyon bildirimi delete this.f; // Bu özellik de kaldırılamaz

Mülklerin Varlığını Kontrol Etme

JavaScript'teki nesneler, özellik kümeleri olarak düşünülebilir ve bir kümedeki üyeliği kontrol edebilmek genellikle yararlıdır - bir nesnenin belirli bir ada sahip bir özelliği olup olmadığını kontrol etmek için. Operatörü kullanarak böyle bir kontrol yapabilirsiniz. içinde yöntemlerini kullanarak Sahip OwnProperty() Ve özellikIsEnumerable() veya sadece mülke erişerek.

in operatörü, sol işlenende bir özellik adı (dize olarak) ve sağ işlenende bir nesne gerektirir. Nesnenin bu ada sahip kendi veya devralınan özelliği varsa true değerini döndürür:

Var nesne = ( x:1 ) nesnede "x"; // true: obj, obj'de kendi "x" "y" özelliğine sahiptir; // false: nesnenin nesnede "y" özelliği "toString" yok; // true: obj, toString özelliğini devralır

Bir nesnenin hasOwnProperty() yöntemi, nesnenin belirtilen ada sahip kendi özelliğine sahip olup olmadığını kontrol eder. Devralınan özellikler için false döndürür:

Varobj = ( x:1 ) obj.hasOwnProperty("x"); // true: nesnenin kendi özelliği "x" vardır obj.hasOwnProperty("y"); // false: nesnenin bir "y" özelliği yok obj.hasOwnProperty("toString"); // false: toString, devralınan bir özelliktir

propertyIsEnumerable() yöntemi, hasOwnProperty() ile karşılaştırıldığında ek kısıtlamalar getirir. Yalnızca belirtilen özellik, numaralandırılabilir özniteliği true olarak ayarlanmış yerel bir özellikse true değerini döndürür. Yerleşik nesne özellikleri numaralandırılamaz. Normal bir JavaScript programı tarafından oluşturulan özellikler, özellikleri numaralandırılamaz yapan aşağıdaki ECMAScript 5 yöntemlerinden biri kullanılmadıkça numaralandırılabilir.

Genellikle, in operatörü yerine, basit bir özellik erişim ifadesi kullanmak ve değerin tanımsız olup olmadığını kontrol etmek için !== operatörünü kullanmak yeterlidir:

Var nesne = ( x:1 ) nesne.x !== tanımsız; // true: obj, "x" özelliğine sahiptir obj.y !== tanımsız; // false: nesnenin bir "y" özelliği yok obj.toString !== tanımsız; // true: obj, toString özelliğini devralır

Ancak in operatörü, bir özelliğe erişime dayalı olarak yukarıdaki tekniği kullanarak ayırt edilemeyen durumlar arasında ayrım yapar. in operatörü, bir özelliğin yokluğunu, tanımsız değerine sahip bir özellikten ayırır.

Özellik numaralandırma

Bireysel özelliklerin varlığını kontrol etmek yerine, bazen mevcut tüm özellikleri tekrarlamak veya bir nesnenin tüm özelliklerinin bir listesini almak gerekir. Bu genellikle bir for/in döngüsü kullanılarak yapılır, ancak ECMAScript 5 standardı iki uygun alternatif sunar.

for/in döngüsü ifadesi, belirtilen nesnenin her bir numaralandırılabilir özelliği (kendi veya devralınan) için döngü gövdesini yürütür ve özelliğin adını döngü değişkenine atar. Nesneler tarafından devralınan yerleşik yöntemler numaralandırılamaz ve programınız tarafından nesnelere eklenen özellikler numaralandırılabilir (özellikleri numaralandırılamaz yapmak için aşağıda açıklanan işlevleri kullanmadıysanız). Örneğin:

// Üç sıralanabilir özelliğe sahip basit bir nesne var user = ( login:"kot86", name:"Alexandr", age:26 ); user.propertyIsEnumerable("toString"); // false, toString - (kullanıcıda n) için yerleşik yöntem console.log(n);

Bazı kitaplıklar, devralınabilmeleri ve tüm nesneler için kullanılabilir hale getirilebilmesi için Object.prototype nesnesine yeni yöntemler (veya başka özellikler) ekler. Ancak, ECMAScript 5 standardının ortaya çıkmasına kadar, bunları yapmanın bir yolu yoktu. ek yöntemler numaralandırılamaz, bu nedenle for/in döngülerinde numaralandırma için uygunlardı. Bu sorunu çözmek için, for/in döngüsü tarafından döndürülen özellikleri filtrelemeniz gerekebilir. Aşağıdakiler, bu tür filtrelemeye ilişkin iki örnektir:

(kullanıcıda n) için ( if (!user.hasOwnProperty(n)) devamı; console.log(n); ) için (kullanıcıda n) ( if (kullanıcı türü[n] === "işlev") devam eder; konsol.log(n); )

for/in döngüsüne ek olarak, ECMAScript 5 standardı özellik adlarını sıralayan iki işlevi tanımlar. İlki, Object.keys(), nesnenin kendi numaralandırılabilir özelliklerinin bir dizi adını döndürür.

Özellikleri sıralayan ikinci ECMAScript 5 işlevi Object.getOwnPropertyNames(). Object.keys() işlevi gibi davranır, ancak yalnızca numaralandırılmış olanların değil, belirtilen nesnenin tüm özelliklerinin adlarını döndürür. ECMAScript 3 uygulamaları, bu tür işlevleri uygulama yeteneğine sahip değildir çünkü ECMAScript 3, bir nesnenin numaralandırılamayan özelliklerini alma yeteneği sağlamaz.

Mülk Okuyucular ve Yazarlar

Bir nesne özelliğinin bir adı, bir değeri ve bir dizi niteliği olduğu yukarıda zaten söylenmişti. ECMAScript 5'te, bir değer, yöntemler olarak bilinen bir veya iki yöntemle değiştirilebilir. okumak (alıcı) Ve kayıtlar (ayarlayıcı). Okuma ve yazma yöntemlerinin tanımlandığı özellikler bazen şu şekilde adlandırılır: erişimcileri olan özellikler bunları basit bir değeri temsil eden veri özelliklerinden ayırt etmek için.

Bir program erişimci yöntemlerle bir özelliğin değerini almaya çalıştığında, yorumlayıcı read yöntemini (argümansız) çağırır. Bu yöntemin döndürdüğü değer, özellik erişim ifadesinin değeri olur. Bir program bir özelliğe değer yazmaya çalıştığında, yorumlayıcı ayarlayıcıyı çağırır ve değeri atama operatörünün sağına iletir. Bu yöntem, özelliğin değerini "ayarlamaktan" sorumludur. Yazma yöntemi tarafından döndürülen değer yok sayılır.

Veri özelliklerinden farklı olarak, erişimci özellikleri yazılabilir bir özniteliğe sahip değildir. Bir özelliğin hem okuma hem de yazma yöntemleri varsa, okuma/yazma olur. Bir özelliğin salt okunur bir yöntemi varsa, salt okunurdur. Ve bir özelliğin yalnızca bir yazma yöntemi varsa, salt yazılır (bu, veri içeren özellikler için mümkün değildir) ve böyle bir özelliğin değerini okuma girişimleri her zaman tanımsız döndürür.

Erişimcilerle bir özelliği tanımlamanın en kolay yolu, nesne değişmezlerini tanımlamak için genişletilmiş sözdizimini kullanmaktır:

Var nesne = ( // data_prop verisine sahip normal özellik: değer, // Erişimcilere sahip bir özellik, bir çift fonksiyon olarak tanımlanır get accessor_prop() ( /* fonksiyon gövdesi */ ), set accessor_prop(değer) ( /* işlev gövdesi */ ) );

Erişimci yöntemleriyle özellikler, adları özellik adıyla aynı olan ve işlev anahtar sözcüğünün get ve/veya set ile değiştirildiği bir veya iki işlev olarak tanımlanır.

Özellik adını, özelliğe erişimi kontrol eden işlevden ayırmak için iki nokta üst üste kullanmanız gerekmediğini, ancak yöntemi diğer yöntemlerden veya verilerle özelliklerden ayırmak için işlev gövdesinden sonra virgül kullanmanız gerektiğini unutmayın.

Örneğin, bir düzlemdeki bir noktanın Kartezyen koordinatlarını temsil eden aşağıdaki nesneyi düşünün. X ve Y koordinatlarını temsil etmek için, verilerle olağan özelliklerin yanı sıra eşdeğerini almanıza izin veren erişimcilere sahip özelliklere sahiptir. kutupsal koordinatlar puan:

Var p = ( // x ve y normal okuma/yazma veri özellikleridir x: 1.0, y: 1.0, // r iki erişimciye sahip bir okuma/yazma özelliğidir. // Yöntem erişiminden sonra virgül eklemeyi unutmayın get r() ( Math.sqrt(this.x*this.x + this.y*this.y); ), set r(newvalue) ( ​​var oldvalue = Math.sqrt(this.x*this. x + this.y*this.y); var oranı = yenideğer/eskideğer; this.x *= oran; this.y *= oran; ), // theta, tek bir okuma yöntemiyle salt okunur bir özelliktir get theta () ( dönüş Math.atan2(this.y, this.x); ) );

Yukarıdaki okuma ve yazma yöntemlerinde this anahtar sözcüğünün kullanımına dikkat edin. Yorumlayıcı, bu işlevleri tanımlandıkları nesnenin yöntemleri, yani. işlevin gövdesinde bu, nokta nesnesine atıfta bulunacaktır. Bu, r özelliğinin okuyucusunun this.x ve this.y gibi x ve y özelliklerine başvurmasına izin verir.

Erişimcili özellikler, tıpkı normal veri özellikleri gibi miras alınır, bu nedenle yukarıda tanımlanan p nesnesi, diğer nokta nesneleri için bir prototip olarak kullanılabilir. Yeni nesneler kendi x ve y özelliklerini tanımlayabilir ve r ve teta özelliklerini devralırlar.

nesne nitelikleri

Tüm nesnelerin prototip, sınıf ve genişletilebilir özellikleri vardır. Bu özelliklerin tümü aşağıdaki alt bölümlerde açıklanmıştır.

prototip niteliği

Nesnenin prototip niteliği, özelliklerin devralındığı nesneyi belirtir. Kodda bir prototip referansı oluştuğunda, bunun bir prototip niteliği değil, bir nesnenin normal bir özelliğine atıfta bulunduğunu anlamak önemlidir.

Prototip niteliği, nesne oluşturulduğunda ayarlanır. Değişmez değerlerle oluşturulan nesneler için prototip, Object.prototype'dir. new operatörüyle oluşturulan bir nesnenin prototipi, yapıcının prototip özelliğinin değeridir. Ve Object.create() ile oluşturulan bir nesnenin prototipi, bu işlevin (boş olabilir) ilk argümanıdır.

ECMAScript 5 standardı, herhangi bir nesnenin prototipini, yönteme iletirseniz tanımlama yeteneği sağlar. Object.getPrototypeOf(). ECMAScript 3'te eksik eşdeğer fonksiyon, ancak genellikle bir obj nesnesinin prototipini obj.constructor.prototype ifadesini kullanarak tanımlayabilirsiniz.

Yeni operatörle oluşturulan nesneler genellikle özelliği devralır. kurucu Nesneyi oluşturmak için kullanılan yapıcı işlevi ifade eden A. Ve yukarıda bahsedildiği gibi, yapıcı fonksiyonların, o kurucu ile oluşturulan nesnelerin prototipini tanımlayan bir prototip özelliği vardır.

Nesne değişmezleri veya Object.create() ile oluşturulan nesnelerin, Object() yapıcısına başvuran bir yapıcı özelliği aldığını unutmayın. Bu nedenle, yapıcı.prototip, nesne değişmezleri için gerçek prototipi ifade eder, ancak bu genellikle Object.create() çağrılarak oluşturulan nesneler için geçerli değildir.

Bir nesnenin başka bir nesnenin prototipi (veya prototip zincirindeki bir bağlantı) olup olmadığını belirlemek için yöntemi kullanın. isPrototypeOf(). p'nin nesnenin prototipi olup olmadığını öğrenmek için p.isPrototypeOf(obj) ifadesini yazın. Örneğin:

Varp = (x:1); // Prototip nesnesini tanımlayın. varobj = Object.create(p); // Bu prototip ile bir nesne oluşturun. p.isPrototypeOf(obj); // => true: obj, p'yi miras alır Object.prototype.isPrototypeOf(p); // => true: p, Object.prototype'ı devralır

sınıf özelliği

Bir nesnenin sınıf niteliği, nesnenin türü hakkında bilgi içeren bir dizedir. Ne ECMAScript 3 ne de ECMAScript 5 bu özniteliği değiştirme yeteneği sağlamaz ve değerini belirlemek için yalnızca dolaylı yollar sağlar. Varsayılan olarak, toString() yöntemi (Object.prototype öğesinden devralınmıştır) aşağıdaki gibi bir dize döndürür:

Bu nedenle, bir nesnenin sınıfını belirlemek için, nesnenin toString() yöntemini çağırmayı deneyebilir ve sonuçtan sekizinci karakterden sondan bir önceki karaktere kadar olan alt diziyi çıkarabilirsiniz. İşin püf noktası, birçok yöntemin toString() yönteminin diğer, daha kullanışlı uygulamalarını devralmasıdır ve doğru toString() sürümünü çağırmak için Function.call() yöntemini kullanarak dolaylı bir çağrı yapmanız gerekir.

Aşağıdaki örnek, kendisine iletilen herhangi bir nesnenin sınıfını döndüren bir işlevi tanımlar:

// Nesne sınıf adı işlev classof(obj) ( if (obj === null) "Null" döndürür; if (obj === undefined) "Undefined" döndürür; Object.prototype.toString.call(obj).slice döndürür (8,-1); )

Bu classof() işlevi, JavaScript dilinde izin verilen herhangi bir değerden geçirilebilir. Sayılar, dizeler ve boole'ler, üzerlerinde toString() yöntemi çağrıldığında nesneler gibi davranır ve null ve undefined farklı şekilde ele alınır.

genişletilebilir özellik

Bir nesnenin genişletilebilir özniteliği, nesneye yeni özelliklerin eklenip eklenemeyeceğini belirler. ECMAScript 3'te, tüm yerleşik ve kullanıcı tanımlı nesneler dolaylı olarak genişletilebilirdi ve çalışma zamanı nesnelerinin genişletilebilirliği uygulama tarafından tanımlandı. ECMAScript 5'te, tüm yerleşik ve kullanıcı tanımlı nesneler, genişletilemez nesnelere dönüştürülmedikçe genişletilebilirdir ve çalışma zamanı nesnelerinin genişletilebilirliği hala uygulamaya özeldir.

ECMAScript 5 standardı, bir nesnenin genişletilebilirlik niteliğini almak ve değiştirmek için işlevleri tanımlar. Bir nesnenin genişletilmesine izin verilip verilmediğini belirlemek için, yönteme iletilmelidir. Object.isExtensible(). Bir nesneyi genişletilemez yapmak için yönteme iletilmelidir. Object.preventExtensions(). Bir nesne genişletilemez hale getirildikten sonra tekrar genişletilemez hale getirilemeyeceğini unutmayın. Ayrıca, önlemeExtensions() öğesinin çağrılmasının yalnızca nesnenin kendisinin genişletilebilirliğini etkilediğine dikkat edin. Genişletilemez bir nesnenin prototipine yeni özellikler eklenirse, genişletilemez nesne bu yeni özellikleri devralır.

Genişletilebilir özniteliğin amacı, nesnelerin belirli bir durumda "sabitlenmesine" izin vererek değişiklik yapılmasını engellemektir. Genişletilebilir nesne özniteliği genellikle yapılandırılabilir ve yazılabilir özellik öznitelikleri ile birlikte kullanılır, bu nedenle ECMAScript 5, bu öznitelikleri aynı anda ayarlamayı kolaylaştırmak için işlevleri tanımlar.

Yöntem Object.mühür() Object.preventExtensions() yöntemi gibi davranır, ancak yalnızca nesneyi genişletilemez kılmakla kalmaz, aynı zamanda o nesnenin tüm özelliklerini yapılandırılamaz hale getirir. Yani, nesneye yeni özellikler eklenemez ve mevcut özellikler silinemez veya yapılandırılamaz. Ancak, mevcut yazılabilir özellikler yine de değiştirilebilir.

Object.seal() çağrıldığında, nesne önceki durumuna döndürülemez. Bir nesne üzerinde Object.seal() yönteminin çağrılıp çağrılmadığını belirlemek için, Object.isSealed().

Yöntem nesne.dondur() nesnelerin daha da sert sabitlenmesini sağlar. Nesneyi genişletilemez ve özelliklerini yapılandırılamaz hale getirmenin yanı sıra, verilerle tüm yerel özellikleri salt okunur yapar. (Bu, ayarlayıcılara sahip erişimci yöntemlerine sahip nesne özellikleri için geçerli değildir; bu yöntemler yine atama ifadeleriyle çağrılacaktır.) Bir nesnenin Object.freeze() yönteminin çağrılıp çağrılmadığını belirlemek için, Object.isFrozen().

Object.seal() ve Object.freeze() öğelerinin yalnızca kendilerine iletilen nesneyi etkilediğini anlamak önemlidir: o nesnenin prototipini etkilemezler. Programınızın bir nesneyi tam olarak taahhüt etmesi gerekiyorsa, muhtemelen prototip zincirindeki nesneleri de taahhüt etmeniz gerekecektir.

Nesne Serileştirme

Nesne serileştirme, nesneleri daha sonra geri yüklemek için kullanılabilecek bir dize temsil formuna dönüştürme işlemidir. ECMAScript 5, JavaScript nesnelerini seri hale getirmek ve geri yüklemek için yerleşik işlevler sağlar. JSON.stringify() Ve JSON.parse(). Bu işlevler JSON veri alışverişi biçimini kullanır. JSON adı "JavaScript Object Notation"dan (JavaScript nesne gösterimi) gelir ve bu gösterimin sözdizimi JavaScript'teki nesne değişmezleri ve dizilerinin sözdizimine benzer:

Var nesne = (x:1, y:(z:)); // Test nesnesini tanımla var s = JSON.stringify(obj); // s == "("x":1,"y":("z":))" var p = JSON.parse(s); // p, nesnenin bir kopyasıdır

Sözdizimi json formatı JavaScript dilinin sözdiziminin yalnızca bir alt kümesidir ve JavaScript'te izin verilen tüm olası değerleri temsil etmek için kullanılamaz. Desteklenir ve serileştirilebilir ve geri yüklenebilir: nesneler, diziler, dizeler, final Sayısal değerler, doğru, yanlış ve boş. NaN, Infinity ve -Infinity değerleri null olarak serileştirilir. Tarih nesneleri, içinde tarihler bulunan dizeler halinde serileştirilir. ISO biçimi, ancak JSON.parse() bunları dize temsilinde bırakır ve orijinal Date nesnelerini geri yüklemez.

Function, RegExp ve Error nesneleri ve undefined değeri serileştirilemez veya geri yüklenemez. JSON.stringify() işlevi, yalnızca bir nesnenin numaralandırılabilir yerel özelliklerini seri hale getirir. Bir özelliğin değeri serileştirilemezse, özellik basitçe dize gösteriminden çıkarılır. Hem JSON.stringify() hem de JSON.parse(), örneğin seri hale getirilecek bir özellikler listesi veya serileştirme sırasında bir değer dönüştürme işlevi belirterek, serileştirme ve/veya kurtarma işlemini özelleştirmek için kullanılabilecek isteğe bağlı ikinci bir argüman alır.

Son güncelleme: 04/08/2018

Nesne yönelimli programlama, günümüzde uygulama geliştirmede baskın paradigmalardan biridir ve JavaScript'te de OOP'den tam olarak yararlanabiliriz. Aynı zamanda, JavaScript ile ilgili olarak, nesne yönelimli programlamanın bazı özellikleri vardır.

nesneler

Geçmiş konularda, ilkel verilerle çalıştık - sayılar, dizeler, ancak veriler her zaman ilkel türleri temsil etmez. Örneğin, programımızda adı, yaşı, cinsiyeti vb. olan bir kişinin özünü tanımlamamız gerekiyorsa, doğal olarak bir kişinin özünü bir sayı veya dize olarak gösteremeyiz. Kişiyi doğru bir şekilde tanımlamak için birkaç satıra veya sayıya ihtiyacımız var. Bu bağlamda, bir kişi ayrı özelliklere sahip olacak - yaş, boy, ad, soyadı vb.

JavaScript, bunun gibi yapılarla çalışmak için . Her nesne, durumunu tanımlayan özellikleri ve davranışını tanımlayan yöntemleri saklayabilir.

Yeni bir nesne oluşturma

Yeni bir nesne oluşturmanın birkaç yolu vardır.

İlk yol, Object yapıcısını kullanmaktır:

Var user = new Object();

Bu durumda, nesne kullanıcı olarak adlandırılır. Var anahtar sözcüğü kullanılarak herhangi bir sıradan değişken gibi tanımlanır.

Yeni Object() ifadesi, yeni bir nesne oluşturan bir işlev olan bir yapıcı çağrısını temsil eder. Yeni operatör, bir kurucu çağırmak için kullanılır. Bir yapıcıyı çağırmak, aslında normal bir işlevi çağırmaya benzer.

Bir nesne yaratmanın ikinci yolu kaşlı ayraçlar kullanmaktır:

var kullanıcı = ();

Bugüne kadar, ikinci yöntem daha yaygındır.

nesne özellikleri

Bir nesne oluşturduktan sonra üzerinde özellikler tanımlayabiliriz. Bir özelliği tanımlamak için, nesnenin adından sonra nokta ile ayırarak özelliğin adını belirtin ve ona bir değer atayın:

var kullanıcı = (); user.name = "Tom"; kullanıcı yaşı = 26;

Bu durumda, uygun değerlere atanan name ve age adlı iki özellik bildirilir. Bundan sonra, bu özellikleri kullanabiliriz, örneğin değerlerini konsolda gösterebiliriz:

Console.log(kullanıcı.adı); konsol.log(kullanıcı.yaş);

Bir nesneyi tanımlarken özellikleri de tanımlayabilirsiniz:

Var user = ( isim: "Tom", yaş: 26 );

Bu durumda, özelliğe bir değer atamak için iki nokta üst üste karakteri kullanılır ve özellik tanımından sonra virgül (noktalı virgül yerine) konur.

Ayrıca, özellikleri tanımlamanın kısa bir yolu da mevcuttur:

Var name = "Tom"; var yaş = 34; var user = (isim, yaş); konsol.log(kullanıcı.adı); // Tom konsol.log(kullanıcı.yaş); // 34

Bu durumda değişkenlerin isimleri aynı zamanda nesnenin özelliklerinin isimleridir. Ve bu şekilde daha karmaşık yapılar oluşturabilirsiniz:

Var name = "Tom"; var yaş = 34; var user = (isim, yaş); var öğretmen = (kullanıcı, kurs: "JavaScript"); konsol.log(öğretmen.kullanıcı); // (isim: "Tom", yaş: 34) console.log(teacher.course); // JavaScript

Nesne Yöntemleri

Bir nesnenin yöntemleri, davranışını veya gerçekleştirdiği eylemleri tanımlar. Yöntemler fonksiyonlardır. Örneğin, bir kişinin adını ve yaşını gösterecek bir yöntem tanımlayalım:

var kullanıcı = (); user.name = "Tom"; kullanıcı yaşı = 26; user.display = function()( console.log(user.name); console.log(user.age); ); // yöntem çağrısı user.display();

Fonksiyonlarda olduğu gibi, metotlar önce tanımlanır ve sonra çağrılır.

Yöntemler, bir nesne tanımlanırken doğrudan da tanımlanabilir:

Var user = ( isim: "Tom", yaş: 26, ekran: function()( console.log(this.name); console.log(this.age); ) );

Özelliklerde olduğu gibi, iki nokta üst üste kullanılarak bir yönteme bir işlev referansı atanır.

Bu nesne içindeki bir nesnenin özelliklerine veya yöntemlerine erişmek için this anahtar sözcüğü kullanılır. Geçerli nesneye bir referans anlamına gelir.

Ayrıca, iki nokta üst üste ve kelime işlevinin kullanılmadığı yöntemleri tanımlamak için kestirme bir yol da kullanabilirsiniz:

Var user = ( name: "Tom", yaş: 26, display()( console.log(this.name, this.age); ), move(place)( console.log(bu.name, "gider" , yer); ) ); kullanıcı.display(); // Tom 26 kullanıcı move("dükkan"); // Tom dükkana gider

Dizi Sözdizimi

Dizi sözdizimini kullanarak özellikleri ve yöntemleri tanımlamanın alternatif bir yolu da vardır:

var kullanıcı = (); user["ad"] = "Tom"; kullanıcı["yaş"] = 26; user["display"] = function()( console.log(user.name); console.log(user.age); ); // method call user["display"]();

Her özelliğin veya yöntemin adı tırnak işaretleri ve köşeli parantezler içine alınır, ardından bunlara bir değer de atanır. Örneğin, kullanıcı["yaş"] = 26 .

Bu özelliklere ve yöntemlere atıfta bulunurken, nokta gösterimini (user.name) kullanabilir veya şu şekilde erişebilirsiniz: user["name"]

Özellikler ve yöntemler olarak dizeler

Ayrıca, bir nesnenin özelliklerinin ve yöntemlerinin adlarının her zaman dizeler olduğuna dikkat edilmelidir. Yani, önceki nesne tanımını şu şekilde yeniden yazabiliriz:

Var user = ("isim": "Tom", "yaş": 26, "görüntüleme": function()( console.log(user.name); console.log(user.age); ) ); // yöntem çağrısı user.display();

Bir yandan, iki tanım arasında hiçbir fark yoktur. Öte yandan, başlığı bir dizeye sarmanın yardımcı olabileceği durumlar da vardır. Örneğin, özellik adı bir boşlukla ayrılmış iki kelimeden oluşuyorsa:

Var user = ( isim: "Tom", yaş: 26, "tam isim": "Tom Johns", "görüntüleme bilgisi": function()( console.log(user.name); console.log(user.age) ; ) ); konsol.log(kullanıcı["tam ad"]); user["bilgiyi göster"]();

Sadece bu durumda, bu tür özelliklere ve yöntemlere atıfta bulunmak için dizi sözdizimini kullanmalıyız.

Özellikleri kaldırma

Yukarıda bir nesneye dinamik olarak nasıl yeni özellikler ekleyebileceğinizi gördük. Ancak, silme operatörünü kullanarak özellikleri ve yöntemleri de silebiliriz. Ve tıpkı ekleme gibi, özellikleri iki şekilde kaldırabiliriz. İlk yol nokta gösterimini kullanmaktır:

Object.property'yi silin

Veya dizi sözdizimini kullanın:

["özellik"] nesnesini sil

Örneğin, özelliği kaldıralım:

var kullanıcı = (); user.name = "Tom"; kullanıcı yaşı = 26; user.display = function()( console.log(user.name); console.log(user.age); ); konsol.log(kullanıcı.adı); // Tom kullanıcı adını sil; // özelliği sil // alternatif // kullanıcıyı sil["ad"]; konsol.log(kullanıcı.adı); // Tanımsız

Silme işleminden sonra özellik tanımsız olacaktır, bu nedenle ona erişmeye çalıştığınızda program tanımsız olarak dönecektir.

okuyan herkese selamlar bu yayın. Bugün sizi dilin temel aracı olan JavaScript nesnelerine götürmek istiyorum. js'nin çapraz tarayıcı olduğunu ve tüm işletim sistemlerinde (windows, mac os vb.) çalıştığını hatırlatmama izin verin. Nesne yönelimli programlama dillerinden farklı olarak, js'de nesnelerin uygulanması, örneğin C# gibi örneklerin kullanımındaki olağan işlevsellik ve varyasyonlardan önemli ölçüde farklıdır.

Bu nedenle, mevcut makaleyi okuduktan sonra, kodlanmış nesnelerin ana ayırt edici özelliklerini öğrenecek, bunların hangi yollarla oluşturulabileceklerini, güncellenebileceklerini ve silinebileceklerini öğreneceksiniz. Ayrıca özellikler, yöntemler ve yapıcılar konusuna da değineceğim, bunlardan bahsedeceğim. faydalı komutlar ve elbette biraz da miras hakkında. Bence öğrenmeye başlamanın zamanı geldi!

JavaScript'te nesne nedir ve hangi özelliklere sahiptir?

js'de nesneler basit ilişkisel dizilerdir (karma olarak da adlandırılır).

ilişkisel dizi nedir?

Bu, belirli bir öğeyle ilgili ve onu tanımlayan belirli miktarda bilgiyi depolayan bir veri yapısıdır. Tüm veriler yapılandırılır ve "anahtar => değer" olarak birbirine bağlanır.

Örneğin, arabaları tanımlamanız gerekir. Sonra bir avto nesnesi yaratır ve özelliklerini bir dizide tanımlarsınız. Arabanın markasını (adını), rengini (rengini) ve maliyetini (fiyatını) açıklamaya karar verdim. Aşağıda açıklanan görevin uygulama kodunu ekledim.

1 2 3 4 5 var avto = ( isim: "BMW 116i", renk: "siyah", fiyat: 588000 );

var avto = ( isim: "BMW 116i", renk: "siyah", fiyat: 588000 );

Burada "avto" adında bir nesne yaratmanın bir yolunu görüyorsunuz. İsim, renk ve fiyat, uygulama yazılırken ulaşılabilen anahtarlardır.

Bu örnekle öne geçtim, şimdi her şeyi sırayla analiz edeceğiz.

Bir nesne oluşturmanın birkaç yolu vardır:

var auto = (); veya varauto = new Object();

Her iki durumda da iyi bilinen bir ada sahip boş bir nesne oluşturulur, ancak ilk seçenek daha kısa ve yazması daha kolay olduğu için çok daha yaygındır.

mülkler hakkında her şey

Şimdi boş nesneyi parametrelerle doldurmamız gerekiyor. Bunu yapmak için, yukarıda anahtarlar olarak da adlandırdığım özellikleri eklemeniz gerekiyor. Yine, özellikleri bildirmenin iki yolu vardır.

JavaScript'te bu tür parametreleri oluşturmak ve başlatmak için katı bir çerçeve olmadığını belirtmek isterim. Tıpkı kaldırılıp güncellenebilecekleri gibi, kod boyunca yeni özellikler görünebilir.

Böylece tüm anahtarları bir kerede oluşturabilir veya kullanılabilir olduklarında bildirebilirsiniz. Ve bir program yazarken var olmayan anahtarlara atıfta bulunsanız bile, herhangi bir hata olmayacaktır. Bu durumda, "tanımsız" döndürülür.

İlk yol.

Bir nokta aracılığıyla özellikler oluşturma ve bunlara erişme. Bu seçeneği uygulamak için, nesnenin adını yazmanız ve ardından anahtarın adını bir nokta aracılığıyla ona atamanız ve ardından eşittir işaretiyle bir değer atamanız gerekir:

auto.name="BMW 116i"

Ancak bu şekilde mevcut anahtarlara bir öğe daha ekleyeceksiniz:

Bu yöntem, özellik adı zaten biliniyorsa ve değerlerle belirli eylemlerin yapılması gerektiğinde kullanılır.

İkinci yol.

Amaçlarını karşılaştırırsak, ilkinden farklı değil. Ancak, bu yöntemin küçük bir avantajı vardır. Bu seçenek için köşeli parantezler kullanılır:

auto[“ad”] = “ BMW 116i”

Ve güzel bir ekleme, özelliklerin adını herhangi bir dize biçiminde oluşturma yeteneğidir. Örneğin,

auto[“arabanın adı”] = “ BMW 116i”

Köşeli parantez içinde tuşlarla çalışma, bazı parametrelerin kullanıcı tarafından girilip değişkenlerde saklandığı veya özelliklerin adlarının önceden bilinmediği durumlarda kullanılır. Örneğin, kullanıcı seçilen bir arabanın fiyatını talep eder. Çağrılan öğe değişkene yazılır ve yanıt olarak fiyat iletilir:

var auto = (); avto.name = "BMW_116i"; oto.fiyat = 588000; var key = "fiyat"; // arabanın fiyatı istendi alert(avto);

Şimdi özellikleri kaldırmaya geçelim. Burada her şey çok basit. Silmek için komutu kullanın silmek. Dolayısıyla, aşağıdaki son örneğe aşağıdaki 2 satırı eklerseniz:

auto.price'ı sil;

uyarı(otomatik);

Ardından ikinci kez uyarmak için yapılan bir çağrı ile iletişim kutusu “tanımsız” görüntüleyecektir.

Kompaktlık hakkında birkaç kelime

Şu anki aşamada size bir nesnenin nasıl oluşturulacağını ve özelliklerini anlattım. Buna test senaryoları ekledim, ancak en dikkatli olanınız sevgili okuyucular, ilk program kodunun diğerlerinden biraz farklı olduğunu fark etti.

Ve hepsi, verilerin kompakt bir temsilini kullandığı için. Bu, yazılı olarak daha kısa olduğu ve görsel olarak okunması daha kolay olduğu için, anahtarları bildirmenin çok popüler bir yöntemidir.

Özelliklerimizi yineleyelim

JavaScript'te, oluşturulan özellikleri hızla yineleyebilirsiniz. Bunun için daha iyi bilinen özel bir mekanizma sağlandı. Çevrim.

Diğer programlama dillerine aşina iseniz, çoğu zaman döngülerin kelime kullanılarak oluşturulduğunu bilirsiniz. için, daha sonra öğelerin numaralandırılması için koşul parantez içinde yazılır.

Js'de bir döngü gibi görünüyor her biri için C# dilinden. Yapının genel görünümüne göz atın:

for (nesnedeki var nesne) ( // döngü)

obj, numaralandırılmış anahtarların adından sorumlu olduğunda,

nesne - değerleri için.

Şimdi size somut bir örnek.

1 2 3 4 5 6 7 8 var avto = ( isim: "BMW 116i", renk: "siyah", fiyat: 588000 ); for (nesnedeki var nesne) ( alert(obj + ":" + nesne))

var avto = ( isim: "BMW 116i", renk: "siyah", fiyat: 588000 ); for (nesnedeki var nesne) ( alert(obj + ":" + nesne))

Yöntemlere aşina olma zamanı

Komut dosyası dili, yöntemlerin oluşturulmasını sağlar. Bu, herhangi bir zamanda, oluşturulan ilişkisel dizilerin yeteneklerini artıran herhangi bir nesneye bir yöntem veya yöntem ekleyebileceğiniz, kesinlikle basit bir mekanizmadır. Bunlara aynı zamanda özellikler-fonksiyonlar da denir.

Js'nin kendisi bir dereceye kadar çok dinamik ve şaşırtıcı. Farklı türlerdeki öğeleri bu şekilde oluşturabilirsiniz. Bu dili öğrenirken, birçok bildirim birbirine çok benzediğinden karmaşık yapıları ezberlemenize gerek yoktur.

Bu nedenle, bir yöntem oluşturmak için bir nesne bildirmeniz ve ardından tam olarak özellikleri oluşturmaya benzer bir komut yazmaya başlamanız gerekir. Ancak “=”dan sonra yazılan artık bir değer değil, anahtar kelime işlevidir (değişken). Ve sonra küme parantezleri içinde eylemlerin bir listesi bulunur.

İşte bu mekanizmanın uygulanması:

var avto =() avto.name = “BMV” avto.year = 1999 avto.drive = function(k) ( alert(“Araç seyahat”+n+“km.”)) avto.drive(300) avto.drive( 450)

Gördüğünüz gibi, bu örnek, çağrısı başlangıçta aynı olan özellikleri ve yöntemleri içerir.

JS'nin de yapıcıları var mı?

Evet efendim! Bu dilde, " anahtar kelimesini kullanan her şey yeni, otomatik olarak yapıcı olur. Yani, yukarıda boş bir nesnenin bildirimini şu şekilde gördünüz: avto = new Object();. Bu yapıcıdır.

Açıklık için aşağıdaki satırları göz önünde bulundurun.

var bob = new Object();

bob.name="Bob Smith";

Ancak, bu tüm olasılıklar cephaneliği değildir. Js'de kendi kurucularınızı oluşturabilir ve ardından bunları yeni nesneler bildirmek için kullanabilirsiniz.

Bu yüzden, zaten yerel arabalar için özel bir kurucu "yapmak" istiyorum. Adın ile yazılması gerektiğini unutmayın. büyük harf. Bu, işlevlerin ayırt edici özelliğidir. Bunu yapmak için aşağıdaki yazılım uygulamasını yazıyorum:

işlev Otomatik (ad, fiyat) (

this.name = isim;

this.fiyat = fiyat;

Şimdi, sınırsız sayıda nesne oluştururken ve bu yapıcıyı onlara uygularken, hepsi aynı sınıfa ait olacak. Örneğin:

var car1 = new Avto("BMW", 650000);

var car2 = new Avto("Audi", 520000);

Buna ek olarak, yapıcı içinde yöntemler oluşturabilirsiniz.

JavaScript'te kalıtımın özellikleri

Tipik olarak, birçok dilde kalıtım, birbirinden miras alabilen sınıflara dayanır. Ardından "ata sınıfı", "alt sınıf" gibi ifadeleri duyabilirsiniz.

Ancak, js farklıdır. Nesnelerin miras alındığı yer burasıdır.

Tüm kalıtım, nesneler arasındaki "prototip" olarak bilinen dahili bir referansa dayanır. Yönteme bir nokta ile “.prototype” eklerseniz ve ardından prototipin adını yazarsanız, seçilen yöntemin tüm nesneleri bu prototipten miras alınır.

Bir örneğe geçelim.

fonksiyon Taşıma (isim) ( this.name = name this.canDrive = true ) var transport = new Transport ("avto") // bir taşıma nesnesi yarattı fonksiyon Bisiklet (isim) ( this.name = isim ) Bisiklet.prototip = taşıma // bu sınıfın tüm yeni nesnelerinin prototip taşıma olarak kullanılacağını belirtin bike1 = new Bike ("for_sport") bike2= new Bike ("for_child") console.log(bike1.name) console.log(bike2.name ) konsol .log(bike1.canDrive)

Bu konuda, belki de bitireceğim. Size bir betik dilinin temel yönlerinden bahsettim. Ancak bu sadece yüzeysel bir bilgidir. Sonra, daha derine ineceğiz. Bu arada abonelerimin saflarına katılmayı ve makalenin bağlantısını arkadaşlarınızla paylaşmayı unutmayın. İyi şanlar!

Güle güle!

Saygılarımla, Roman Chueshov

Okumak: 97 kez

Bu makalede, JavaScript'te bir nesnenin ne olduğunu, yeteneklerinin neler olduğunu, nesneler arasında hangi ilişkilerin kurulabileceğini ve bundan hangi “yerli” kalıtım yöntemlerinin çıktığını, bunların nasıl etkilediğini olabildiğince eksiksiz ve tutarlı bir şekilde anlatmak istiyorum. performans ve genel olarak ne yaparsınız :)

Makale, geleneksel sınıf-nesne paradigmasının öykünmesi, sözdizimsel şeker, sarmalayıcılar ve çerçeveler hakkında bir kelime İÇERMEZ.

Malzemenin karmaşıklığı makalenin başından sonuna kadar artacaktır, bu nedenle profesyoneller için ilk bölümler sıkıcı ve banal görünebilir, ancak sonrası çok daha ilginç olacak :)

JavaScript'teki nesneler

Birçok makalede "JavaScript'te - her şey bir nesnedir" ifadesi vardır. Teknik olarak, bu tamamen doğru değil, ancak yeni başlayanlar üzerinde doğru izlenim bırakıyor :)

Aslında, bir dilde birçok şey bir nesnedir ve bir nesne olmayan şeyin bile bazı yetenekleri olabilir.

Burada "nesne" kelimesinin "bir sınıfın nesnesi" anlamında kullanılmadığını anlamak önemlidir. JavaScript'teki bir nesne, temel olarak, anahtar/değer çiftlerinden oluşan bir özellikler koleksiyonudur (herkes için daha kolaysa, buna ilişkisel bir dizi veya liste diyebilirler). Ayrıca, anahtar yalnızca bir dize olabilir (dizi öğeleri için bile), ancak değer aşağıda listelenenlerden herhangi bir veri türü olabilir.

Yani JavaScript'te 6 tane var baz türleri veriler Tanımsız (bir değerin olmaması anlamına gelir), Null, Boolean (boolean), String (string), Number (sayı) ve Object (nesne) şeklindedir.
Bu durumda ilk 5 ilkel veri türleri, Object değilken. Ek olarak, Nesne türünün "alt türleri" olduğu koşullu olarak kabul edilebilir: bir dizi (Array), bir işlev (İşlev), bir normal ifade (RegExp) ve diğerleri.
Bu biraz basitleştirilmiş bir tanımdır, ancak pratikte genellikle yeterlidir.

Ek olarak, String, Number ve Boolean ilkel türleri bir şekilde Object'in ilkel olmayan "alt türleri" ile ilişkilidir: String, Number ve Boolean.
Bu, örneğin "Merhaba, dünya" dizesinin hem ilkel bir değer olarak hem de String türünde bir nesne olarak oluşturulabileceği anlamına gelir.
Kısacası bu, programcının ilkel değerlerle çalışırken, nesnelermiş gibi yöntem ve özellikleri kullanabilmesi için yapılır. Ve bununla ilgili daha fazla bilgiyi bu makalenin ilgili bölümünde okuyabilirsiniz.

Bağlantı çalışması

Bağlantı, bir nesneye çeşitli adlar altında erişmenin bir yoludur. Herhangi bir nesneyle çalışma, yalnızca referans olarak gerçekleştirilir.
Bunu bir örnekle gösterelim:
test= function() (alert("Merhaba!" )) //Bir fonksiyon oluşturun (alert("Merhaba!")) (ve hatırladığımız gibi fonksiyon tam teşekküllü bir nesnedir) ve test değişkenini ona referans yapın
test_link=test; //test_link artık fonksiyonumuza da bağlanıyor
Ölçek(); // Merhaba!
test_link(); // Merhaba!


Gördüğümüz gibi, hem birinci bağlantı hem de ikinci aynı sonucu veriyor.
Test adında bir fonksiyonumuz olmadığını ve test değişkeninin bir tür "ana" veya "birincil" bağlantı olmadığını, ancak "test_bağlantısı"nın küçük olduğunu anlamamız gerekiyor.

Fonksiyonumuz, diğer nesneler gibi, sadece bellekte bir alandır ve bu alana yapılan tüm referanslar kesinlikle eşdeğerdir. Ayrıca, bir nesnenin hiç referansı olmayabilir - bu durumda isimsiz olarak adlandırılır ve yalnızca oluşturulduktan hemen sonra kullanılabilir (örneğin, bir işleve geçirilir), aksi takdirde ona erişmek imkansız olacak ve yakında referanssız nesneleri silmekten sorumlu olan çöp toplayıcı (çöp toplama) tarafından yok edilir.

Bunu anlamanın neden bu kadar önemli olduğunu görelim:

test=(prop: "Bazı metin" ) // prop özelliği ile bir nesne oluştur
test_link=test; //Bu nesneye başka bir referans oluştur

Uyarı(test.prop); //Bazı metin

//Nesnenin özelliğini değiştir
test_link.prop="yenimetin";

Uyarı(test.prop); //yenimetin
uyarı(test_link.prop); //yenimetin
/* Özelliğin şurada burada değiştiği söylenebilir - ama değişmez.
Nesne birdir. Böylece özellik bir kez değişti ve referanslar işaret ettikleri yeri göstermeye devam ediyor. */

// Yeni bir özellik ekleyin ve eskisini kaldırın
test.new_prop="merhaba";
test.prop'u silin;

Uyarı(test_link.prop); //tanımsız - artık böyle bir özellik yok
uyarı(test_link.new_prop);

//Bağlantıyı kaldır
testi sil;
uyarı(test.new_prop);
/*Bu noktada betik bir hata verecek çünkü test artık mevcut değil ve test.new_prop mevcut bile değil */
uyarı(test_link.new_prop); //Merhaba
/* ve burada her şey yolunda, çünkü nesnenin kendisini değil, sadece ona bir bağlantıyı sildik. Şimdi nesnemiz tek bir bağlantı ile gösteriliyor test_link */

//Yeni bir nesne oluştur
test=test_bağlantısı; //Önce test bağlantısını tekrar oluşturun
test_link=(prop: "bir metin") //Ve işte yeni nesne

Uyarı(test_link.prop); //Bazı metin
uyarı(test.prop); //Tanımsız
/* Yeni bir nesne oluşturmak referans bağlantısını keser ve şimdi test ve test_link farklı nesnelere işaret eder.
Aslında bu, test_link'i silip yeniden oluşturmaya eşdeğerdir, ancak zaten başka bir nesneye işaret eder */
uyarı(test.new_prop); //merhaba - şimdi test ilk nesnemize bir referans içeriyor


* Bu kaynak kodu, Kaynak Kodu İşaretleyici ile vurgulanmıştır.

Nesnelerin bu davranışı genellikle acemi geliştiriciler için birçok soru ortaya çıkarır, bu yüzden bu metnin biraz netlik getireceğini umuyorum. Eğer bir referans değil de nesnenin gerçekten yeni, bağımsız bir kopyasını yaratmak istiyorsak, bunu yapmanın tek yolu yeni bir nesne yaratmak ve gerekli özellikleri oraya kopyalamaktır.

Ayrıca, yukarıdaki eğlenceli efektlere ek olarak, nesnelerle referans olarak çalışmanın, aynı zamanda önemli olan bellek tasarrufu sağladığını da belirtmekte fayda var. yaygın kullanım programın farklı yerlerinde bir nesne.

ilkel değerler

Yukarıda bahsettiğim gibi, String ve Number veri türleri, nesneler veya ilkel değerler olabilir.
nesne= new String("merhaba"); // Nesne olarak bir dize oluştur
basit = "merhaba"; //İlkel bir değer oluştur

uyarı(nesne); //Merhaba
uyarı(basit); // merhaba - her şey tahmin edilebilirken

Uyarı(nesne.uzunluk); // String türündeki bir nesne, stringin uzunluğunu saklayan bir length özelliğine sahiptir.
uyarı(basit uzunluk); ///6
/* simple bir nesne olmasa da, bir String nesnesiyle aynı özelliklere erişebiliriz. Oldukça kullanışlı */

Obj.prop="metin";
basit.prop="metin";

Uyarı(obj.prop); //metin - obj normal bir nesne olduğundan, ona kolayca bir özellik daha verebiliriz
uyarı(simple.prop); //tanımsız - ancak basit bir nesne değildir ve bu sayı bizim için çalışmayacaktır

* Bu kaynak kodu, Kaynak Kodu İşaretleyici ile vurgulanmıştır.


Aynısı Number ve Boolean için de geçerlidir (uzunluk özelliğine sahip olmamaları dışında, ancak bir dizi başka harika özellik vardır).
Nesne olarak dizeleri ve sayıları kullanmanın pratik bir faydası yoktur, çünkü ilkel değerlerle çalışmak daha uygundur, ancak gerekli tüm işlevleri korur. Ancak resmi tamamlamak için bu mekanizmayı anlamak gerekir.

İlkel değerleri kullanmayı değişmez değerlerle karıştırmayın - örneğin, "test=new Array()" veya "test=" gibi bir dizi oluştursak da sonuç aynı nesne olacaktır. Herhangi bir ilkel değer elde etmeyeceğiz.

Nesneler Oluşturma ve Kullanma

Dolayısıyla sınıf nesnesi paradigmasının uygulandığı dillerden farklı olarak, daha sonra sınıf nesnesi oluşturmak için önce bir sınıf oluşturmamız gerekmez. Aşağıdaki örnekte yapacağımız gibi hemen bir nesne oluşturabiliriz:
test=(
simple_property: "Merhaba" ,
nesne_özelliği :(
user_1: "Petya" ,
user_2: "Vasya"
},
işlev_özelliği: işlev(kullanıcı)(
alert(bu .simple_property + ", " + bu .object_property);
}
}

test.function_property("user_1"); //Merhaba Petya.

* Bu kaynak kodu, Kaynak Kodu İşaretleyici ile vurgulanmıştır.


Önümüzde, isimlerinin kendileri için konuştuğunu umduğum 3 özelliği olan bir test nesnesi var. En önemlisi, işlevi içeren function_property özelliğiyle ilgileniyoruz. Böyle bir işlev, nesne yöntemi olarak adlandırılabilir.

İşlevimiz, işlevin çağrıldığı nesneye bir işaretçi (yani bir başvuru) olan this anahtar sözcüğünü iki kez kullanır. Yani this.simple_property=test.simple_property="Merhaba" ve this.object_property=test.object_property="Peter".

Bunun her zaman işlevin çağrıldığı nesneye işaret ettiği ve ait olduğu nesneye değil, açıkça anlaşılmalıdır. Bu, bu örnekte aynı nesne olmasına rağmen, bu her zaman böyle değildir.

test.function_property("user_1"); //Merhaba Petya.

Test2=yeni Nesne(); // yeni bir nesne yaratmanın başka bir şekli, test2=()

Test.function_property.call(test2, "user_1" ); //hata
/* Çağrı yöntemi, başka bir nesne adına bir işlevi çağırmanıza izin verir. Bu durumda, test nesnesinin function_property yöntemini çağırırız ve bu, artık test nesnesine değil, test2 nesnesine işaret eder. Dan beri içinde object_property özelliği yok, o zaman this.object_property'yi almaya çalıştığınızda betik bir hata verecek */

// durumu düzeltmeye çalış
test2.simple_property="İyi günler" ;
test2.object_property=test.object_property; //Bu durumda, kodu tekrarlamamak için nesnenin referansını kullanacağız.

Test.function_property.call(test2, "user_1" ); //İyi günler Petya.


* Bu kaynak kodu, Kaynak Kodu İşaretleyici ile vurgulanmıştır.

Bir nesneyi oluşturmak ve kullanmak için net adımlar olmadığı da örnekten açıkça anlaşılmalıdır. Bir nesne herhangi bir zamanda herhangi bir şekilde değiştirilebilir - kullanımdan önce, sonra ve hatta kullanım sırasında. Bu aynı zamanda "geleneksel" OOP'den önemli bir farktır.

yapıcı

Yukarıdaki örnekte, biraz benzerliği olan 2 nesne oluşturduk. Hem orada hem de simple_property ve object_property özellikleri vardı. Açıkçası, gerçek kod yazarken, aynı veya basitçe benzer nesneler oluşturma görevi de sıklıkla ortaya çıkar. Ve elbette, bu tür her bir nesneyi manuel olarak oluşturmak zorunda değiliz.

Tasarımcı kurtarmaya gelecek. JavaScript'teki yapıcı bir sınıfın parçası değildir (çünkü sınıf yoktur), sadece bağımsız bir işlevdir. En yaygın işlev.

make_me= fonksiyon adı)(
alert("Uzatıldım");
bu .name=_name;

}


/* Bakalım burada neler oluyor. Tercüman yeni operatörü görür ve sağında ne olduğunu kontrol eder. Çünkü make_me bir işlevdir ve yapıcı olarak kullanılabilir, bellekte yeni bir nesne oluşturulur ve make_me işlevi bu yeni nesneye işaret ederek yürütülür. Daha sonra, bu nesneye, _name argümanından ve show_name yönteminden değer atanan name özelliği eklenir. Ayrıca (hangi noktada bilmiyorum ama önemli değil) çocuk değişkeni yepyeni, henüz doğmuş nesnemizi işaret etmeye başlar */

Alert(child.name); // Vasya
child.show_name(); // Vasya


child2.show_name(); //Peter

child2.show_name=function() (uyarı( "Adımı Söylemeyeceğim");} // Nesnelerimizi istediğimiz zaman değiştirebileceğimizi unutmayın
child2.show_name(); // adımı söylemeyeceğim

child.show_name(); //Vasya - çocuklar birbirlerini hiçbir şekilde etkilemez


* Bu kaynak kodu, Kaynak Kodu İşaretleyici ile vurgulanmıştır.

Bir kurucuyu bir babayla da karşılaştırabilirsiniz - bir çocuğu doğurur, ona belirli nitelikler verir, ancak yaratıldıktan hemen sonra çocuk ebeveynden tamamen bağımsız hale gelir ve kardeşlerinden çok farklı olabilir.
Makalenin başındaki veri türlerinin tanımını hatırlarsak, Nesne ve alt türlerinin (Fonksiyon, Dizi ve diğerleri) aslında oluşturulan nesneye bir işlev, dizi vb.

Yani, bu zaten çok daha iyi. Artık bazı desenlere göre nesneler yaratma yeteneğine sahibiz. Ancak, her şey iyi değil. İlk olarak, yarattığımız her nesne ve tüm özellikleri ve yöntemleri, büyük ölçüde tekrarlanmalarına rağmen bellekte ayrı bir yer kaplar. İkincisi, ebeveyn ve çocuk arasındaki ilişkiyi korumak ve tüm alt nesneleri bir kerede değiştirebilmek istiyorsak ne olur? Bir prototip yardımımıza gelecek.

Prototip

Her çocuğun bir babası ve annesi olduğu gibi (en azından biyolojik anlamda), JavaScript'teki her nesne de öyle. Ve baba, kararlaştırdığımız gibi bir tasarımcı olarak çalışıyorsa, o zaman anne sadece bir prototiptir. Bakalım nasıl olacak:
make_me= fonksiyon adı)(
alert("Uzatıldım");
bu .name=_name;
this .show_name=function() (uyarı(bu .name);)
}
/*
Fonksiyon anahtar sözcüğünü gören yorumlayıcı, bunun sağındaki kodu kontrol eder ve her şey yolunda - hafızada yeni bir nesne yaratır, bu da bizim fonksiyonumuzdur. Ardından, otomatik olarak (programcının katılımı olmadan), bu işlev için boş bir nesneye atıfta bulunarak bir prototip özelliği oluşturulur. Manuel olarak yapsaydık make_me.prototype=new Object(); gibi görünürdü.

Ardından, bu nesneye (prototip özelliği tarafından işaret edilir) otomatik olarak işleve geri dönen bir yapıcı özelliği de verilir. Böyle bir döngüsel bağlantı ortaya çıkıyor.

Şimdi (yapıcı: ...burada bir fonksiyona referans...) şeklinde tanımlanabilecek bu nesne, fonksiyonun prototipidir.
*/

//Nesne - gerçekten de bir nesne
alert(typeof make_me.prototype.constructor); //Fonksiyon bizim fonksiyonumuzdur
alert(make_me.prototype.constructor === make_me); //doğru

// make_me işlev prototipine yeni bir yöntem ekleyin

çocuk=yeni make_me("Vasya"); // fırlatıldım
/* Şimdi, önceki örnekte açıklanan her şeye ek olarak, alt nesnede make_me.prototype ile aynı nesneye işaret eden ek bir gizli özellik [] oluşturulur. Çünkü özellik gizlidir, değerini ne görebiliriz ne de değiştirebiliriz - ancak daha sonraki çalışmalarda önemli bir rol oynar */

Alert(child.name); // Vasya
child.show_name(); // Vasya

Child.set_name("Kolya");
/* İlk olarak, yorumlayıcı alt nesne üzerinde set_name yöntemini arar. Orada olmadığı için çocukta aramaya devam eder.[ özelliği, onu orada bulur ve çalıştırır. */
child.show_name(); //Kolya - şimdi Vasya'nın adı Kolya :)

Make_me.prototype.show_name2=function () (alert("Merhaba, " + bu .name;) //Çünkü prototip normal bir nesnedir, onu anında değiştirebiliriz

Child2=new make_me("Peter");
child2.show_name2(); //Merhaba Petya
child.show_name2(); //Merhaba Kolya - prototipte yapılan değişiklikler sadece yeni oluşturulan nesneleri değil, tüm eskileri de etkiler

child2.show_name2=işlev () (uyarı( "Adımı Söylemeyeceğim");} //Bu nesnedeki (ve yalnızca içindeki) yeni show_name2 yöntemi, deyim yerindeyse, prototipteki eski yöntemin "üzerine yazarken", nesnenin kendisini hala değiştirebiliriz.
child2.show_name2(); //Adımı söylemeyeceğim - çünkü şimdi kendi show_name2 yöntemimiz var, sonra çağrılır ve prototip aranmaz

child.show_name2(); //Merhaba Kolya - burada her şey aynı

Make_me.prototype=(prop: "merhaba" ) //Prototipi yeniden yaratmayı deneyelim

Alert(alt. prop); //Tanımsız
child.show_name2(); //Merhaba Kolya
/* Referansa göre çalışmanın ne olduğunu hatırlarsanız, her şey açıktır. Prototipin yeniden oluşturulması bağlantıyı keser ve şimdi alt ve alt2 nesnelerinin [] özelliği bir nesneye (eskiden make_me işlevinin prototipiydi) ve make_me.prototype özelliği yeni olan başka bir nesneye işaret eder. make_me işlevinin prototipi */

Child3=new make_me("Oleg");
uyarı(child3.prop); // merhaba - beklendiği gibi


* Bu kaynak kodu, Kaynak Kodu İşaretleyici ile vurgulanmıştır.

Örnekten de anlaşılacağı gibi, baba anneye sadık kaldığı sürece (yani işlevin prototipi aynı kaldığı sürece), tüm çocuklar anneye bağımlıdır ve annedeki tüm değişikliklere duyarlıdır. Ancak, ebeveynler boşanır boşanmaz (tasarımcı prototipi diğerine değiştirir) - çocuklar hemen her yöne dağılır ve daha fazla bağlantı onlarla değil.

Terminoloji hakkında biraz
Yapıcı ile prototip arasındaki birincil bağlantı kopmadığı sürece aşağıdaki resmi görebiliriz:

make_me= fonksiyon adı)(
alert("Uzatıldım");
bu .name=_name;
this .show_name=function() (uyarı(bu .name);)
}

Make_me.prototype.set_name=function (_name) (bu .name=_name;)
çocuk=yeni make_me("Vasya");

Alert(typeof make_me.prototype); //nesne - işlevin bir prototip özelliği var
uyarı(typeofchild.prototype); //tanımsız - oluşturulan nesnenin bir prototip özelliği YOKTUR
alert(child.constructor.prototype === make_me.prototype); //true - ancak nesnenin make_me yapıcı işlevine işaret eden bir yapıcı özelliği vardır, bu da sırayla bir prototip özelliğine sahiptir


* Bu kaynak kodu, Kaynak Kodu İşaretleyici ile vurgulanmıştır.

Konuyla ilgili çok sayıda forum okuduktan sonra fark ettiğim gibi, insanların temel sorunu, bir işlevin prototip özelliği ile o işlevle oluşturulan bir nesnenin gizli [] özelliğini karıştırmalarıdır.
Bu özelliklerin her ikisi de aynı nesneye referanslardır (prototip ile yapıcı arasındaki birincil bağlantı kopmadığı sürece), ancak yine de farklı adlara sahip farklı özelliklerdir, bunlardan biri programcı tarafından kullanılabilir ve diğer değildir.

Yapıcının prototipinden bahsediyorsak, bunun her zaman prototip özelliği olduğunu ve oluşturulan nesnenin prototipinden bahsediyorsak, bunun gizli özellik olduğunu her zaman açıkça anlamalısınız [].

Miras

Artık biliyoruz ki her nesne gizli bağlantı prototip başına ve her prototip normal bir nesnedir.
En hassas okuyucular zaten özyinelemenin kokusunu almış :)
Nitekim, beri Bir prototip normal bir nesnedir, o zaman sırayla prototipine bir referansı vardır ve bu böyle devam eder. Prototip hiyerarşisi bu şekilde uygulanır.
kuş= işlev()() //Bu kuşun kurucusu
bird.prototype.cry=işlev ()(alert("Ağla!" );) // Kuş çığlık atabilir
bird.prototype.fly=function ()(alert("Uçuyorum!" );) //ve uç

Ördek=fonksiyon () ()
ördek.prototip=yeni kuş();
duck.prototype.cry=fonksiyon ()(alert("Ağla!" );) // Ördek farklı şekilde çığlık atıyor
ördek.prototype.constructor=ördek; //Prototip.constructor özelliğini eğilmeye zorla çünkü aksi takdirde kuşa atıfta bulunacaktır

Billy = yeni ördek(); // Billy bizim ördeğimiz
billy fly(); //Uçuyorum! - Billy uçabilir çünkü o bir kuş
billy.cry(); // vak vak! - Billy ördek olduğu için şarlatan diye bağırıyor


* Bu kaynak kodu, Kaynak Kodu İşaretleyici ile vurgulanmıştır.

Böylece herhangi bir iç içe yerleştirme düzeyi hiyerarşisi uygulayabilirsiniz.

yıldız işareti

Şimdi, tüm bunlar hakkında çok şey bildiğimize göre, bu üç satırda ne kadar olduğunu anlamaya çalışalım.
make_me= işlev()()
çocuk=yeni make_me();
uyarı(child.toString()); //çıktılar

* Bu kaynak kodu, Kaynak Kodu İşaretleyici ile vurgulanmıştır.

İlk satırda yeni bir fonksiyon ve bu fonksiyona işaret eden make_me değişkeni oluşturuyoruz. Bu, make_me'ye işaret eden bir yapıcı özelliği içeren make_me.prototype adlı bir işlev prototipi oluşturur.
Ama hepsi bu değil :)
Çünkü make_me işlevi de bir nesnedir, o zaman sırayla bir babası ve annesi vardır, yani. yapıcı ve prototip. Yapıcısı, Function() dilinin yerel bir işlevidir ve prototipi, call, application, vb. yöntemlerini içeren bir nesnedir. - bu prototip sayesinde bu yöntemleri herhangi bir fonksiyonda kullanabiliriz. Bu nedenle make_me işlevi, Function.prototype'a işaret eden bir [] özelliğine sahiptir.

Buna karşılık, Function yapıcısının prototipi de, yapıcısı (sürpriz!) Object (yani Function.prototype.[].constructor===Object) olan bir nesnedir ve prototip, standart özellikleri içeren bir nesnedir. ve toString, hasOwnProperty ve diğerleri gibi nesnenin yöntemleri (başka bir deyişle - Function.prototype.[]["hasOwnProperty"] - bu, tüm türetilmiş nesnelerde kullanabileceğimiz yöntemle tamamen aynıdır - ve bu tam olarak bu nesnenin kendi yöntemidir ve miras alınmaz). Bu ilginç yolla, her türlü nesnenin Object'ten türetildiğini keşfederiz.

Daha fazla devam edebilir miyiz? Değil çıkıyor. Object.prototype, kendi prototipine sahip olmadığı için tam olarak bir nesnenin temel özelliklerini içerir. Object.prototype.[]=null; Bu noktada, bir özellik veya yöntem arayışında prototip zinciri boyunca yolculuk durur.

Bir başka ilginç gerçek, Object'in yapıcısının Function olmasıdır. Onlar. Object.[].constructor===İşlev.
Başka bir döngüsel başvuru vardır - Object yapıcısı bir Function'dır ve Function.prototype yapıcısı bir Object'tir.

Örneğimize geri dönelim. Fonksiyonun nasıl oluşturulduğunu zaten anladık, şimdi ikinci satıra geçelim. Burada yapıcısı make_me işlevi olan ve prototipi make_me.prototype olan bir alt nesne yaratıyoruz.

Üçüncü satırda yorumlayıcının çocuktan çocuğa.[] (aka make_me.prototype), sonra çocuğa.[].[] (diğer adıyla Object.prototype) zincirinde nasıl yukarı çıktığını görüyoruz ve zaten orada yürütmeyi başlatan toString yöntemini bulur.

kirlilikler

JavaScript'te mümkün olan tek yol prototipler yoluyla kalıtım gibi görünebilir. Bu doğru değil.
Kurallardan çok fırsatlar sunan çok esnek bir dille uğraşıyoruz.

Örneğin, istersek prototipleri hiç kullanamayız, ancak mixins kavramını kullanarak programlayabiliriz. Bunun için eskimize ihtiyacımız olacak. iyi arkadaşlar- inşaatçılar.

//Bu bir insan yapıcıdır
adam=işlev() (
bu .live=işlev ()(alert("yaşıyorum" );) // Bir kişi nasıl yaşayacağını bilir
bu .walk=function ()(alert("yürüyorum" );) // Bir kişi yürüyebilir
}

//Bu, şairin kurucusudur
şair=işlev()(
bu .kill=işlev ()(uyarı( "Şair adamı öldürdü");} // Bir şair bir adamı öldürebilir
this .live=function()(alert("Öldüm" );) //Bundan ölecek
}

vladimir=yeni adam(); //Vladimir bir erkek
vladimir.live(); // yaşıyorum - o yaşıyor
vladimir.walk(); // Ben yürüyorum - o yürüyor

Şair.çağrı(vladimir); // vladimir nesnesi için şair yapıcısını yürütün
vladimir.kill(); // Şair bir adam öldürdü
vladimir.live(); //Ben ölüyüm

// Ve şimdi odak
man.call(vladimir);
vladimir.live(); //Yaşıyorum


* Bu kaynak kodu, Kaynak Kodu İşaretleyici ile vurgulanmıştır.

Bu örnekte ne görüyoruz? İlk olarak, aynı hiyerarşide olmayan birkaç nesneden kalıtım olasılığıdır. Örnekte 2 tane var ama istediğiniz kadar olabilir.
İkincisi, herhangi bir hiyerarşinin olmamasıdır. Özelliklerin ve yöntemlerin yeniden tanımlanması, yalnızca kurucuların çağrıldığı sıraya göre belirlenir.
Üçüncüsü, bu, bir nesneyi daha dinamik bir şekilde değiştirme yeteneğidir ve prototipi değiştirirken olduğu gibi tüm torunları değil, ayrı bir nesnedir.

Upd: Kapanışlar ve özel mülkler

Zaten oldukça büyük olan bu makaleyi şişirmemek için, JavaScript'te Closures in JavaScript yazısına bir bağlantı veriyorum, burada bununla ilgili ayrıntılı olarak yazılmıştır.

Bütün bunlarla şimdi ne yapmalı

Yukarıda söylediğim gibi, bireysel nesnelerin keyfi modifikasyonu, yapıcıların ve karışımların kullanımı ve prototiplerin esnekliği, programcının her açıdan hem korkunç hem de harika kod oluşturmasına izin veren araçlardır, yeteneklerdir. Sadece hangi görevleri, hangi yollarla çözdüğümüzü, hangi hedeflere ulaştığımızı ve bunun için ne kadar ödediğimizi anlamak önemlidir.

Ayrıca, özellikle Internet Explorer 6 ve 7 sürümleri için geliştirme hakkında konuşuyorsak, fiyat sorunu oldukça önemsizdir.
1. Hafıza - burada her şey basit. Tüm tarayıcılarda, prototipler üzerindeki kalıtım, yapıcılar aracılığıyla yöntemler oluşturmaya kıyasla çok daha az bellek kaplar. Ayrıca, ne kadar çok yöntem ve özelliğe sahip olursak, fark o kadar büyük olur. Bununla birlikte, bin tane özdeş nesnemiz yoksa, sadece bir tane varsa, o zaman bellek tüketiminin her durumda küçük olacağını hatırlamakta fayda var, çünkü dikkate alınması gereken başka faktörler var.
2. İşlemci süresi - burada ana incelikler Microsoft'un tarayıcılarıyla tam olarak bağlantılıdır.
Bir yandan, bir yapıcı aracılığıyla yöntemlerin ve özelliklerin oluşturulduğu nesneler, bir prototip aracılığıyla olduğundan çok daha yavaş (bazı durumlarda onlarca ve yüzlerce kez) oluşturulabilir. Ne kadar çok yöntem, o kadar yavaş. Bu nedenle, komut dosyası başlatma sırasında IE'de birkaç saniye donarsanız, bu yönde kazmak için bir neden vardır.

Öte yandan, bir nesnenin kendi yöntemleri (bir kurucu aracılığıyla oluşturulan) prototip yöntemlerinden biraz daha hızlı çalışabilir. Bu tarayıcıda bir yöntemin yürütülmesini hızlandırmak için umutsuzca gerekliyse, bunu hesaba katmanız gerekir. Hızlandırılanın (yani nesnede arama yapan) yöntem çağrısı olduğunu ve yürütmesinin olmadığını unutmayın. Bu nedenle, yöntemin kendisi bir saniye boyunca yürütülürse, performansta fazla bir artış görmezsiniz.

Diğer tarayıcılarda, nesne oluşturma ve yöntemlerini çağırma zamanının her iki yaklaşım için yaklaşık olarak aynı olduğu benzer sorunlar gözlemlenir.

not Genellikle bu tür makalelerde yazar, ya prototip kalıtımına dayalı sınıf-nesne kalıtımını uygulamaya çalışan bir çeşit sarmalayıcı ya da prototip kalıtımı için sadece sözdizimsel şeker önerir. bilerek yapmıyorum çünkü Bence bu yazının anlamını anlayan bir kişi kendisi için herhangi bir sarmalayıcı ve daha birçok ilginç şey yazabilir :)

Etiketler: Etiketler ekle