__proto__ VS. JavaScript'te prototip


785

Bu şekil yine her nesnenin bir prototipi olduğunu göstermektedir. Yapıcı işlevi Foo'nun kendine ait __proto__olan Function.prototype olan ve onun da __proto__özelliği aracılığıyla tekrar Object.prototype'e gönderme yapan kendi işlevi vardır . Böylece, tekrarlayın, Foo.prototype, Foo'nun b ve c nesnelerinin prototipini ifade eden açık bir özelliğidir.

var b = new Foo(20);
var c = new Foo(30);

Arasındaki farklar nelerdir __proto__ve prototype?

resim açıklamasını buraya girin

Şekil dmitrysoshnikov.com'dan alınmıştır .



5
Yukarıdan aşağıya veya aşağıdan yukarıya bir tercih meselesi olduğunu düşünüyorum. Aslında bu şekilde tercih ederim, böylece bir şeyin nereden geldiğini bulana kadar diyagramı izleyebilirim.
Mike Lippert

1
JavaScript'in y.constructor'ı y .__ proto __. Ayrıca Object.prototype'ın Object.prototype .__ proto__ null olarak ayarlanmış prototip kalıtım zincirinin en üstünde nasıl oturduğunu seviyorum. Ayrıca şemanın programcının nesneleri 1 örnek, 2. kurucu, 3. yeni anahtar kelime ile somutlaştırıldığında bu örneklerle ilişkilendirdiği prototipler olarak nasıl düşündüğünün üç sütunlu kavramsal bir görselleştirmesini seviyorum.
John Sonderson

Diyagram gibi bir şey izledikten sonra hemen mantıklı youtube.com/watch?v=_JJgSbuj5VI btw
mlvljr

Ve şimdi, cevapları okuduğumda , yukarıdaki videoyu gerçekten tavsiye etmek zorunda hissediyorum , çünkü gerçekten neler olup bittiğine dair kristal temiz (ve WTFy olmayan) bir açıklama var :)
mlvljr

Yanıtlar:


765

__proto__yöntemleri aramak için arama zincirinde kullanılan gerçek nesnedir, vb. prototypeile __proto__bir nesne oluşturduğunuzda oluşturmak için kullanılan nesnedir new:

( new Foo ).__proto__ === Foo.prototype;
( new Foo ).prototype === undefined;

239
Ah! Bu nedenle prototype, örneklerin kendisinde (veya diğer nesnelerde) değil, yalnızca yapıcı işlevlerinde kullanılabilir.
rvighne

43
@rvighne: prototypebunlar türetilmiştir beri fonksiyonları üzerine yalnızca Function, Functionve Objectfakat başka bir şey değil. Ancak, __proto__her yerde kullanılabilir.
Tarik

19
Yani __proto__süre kaydedilir ve prototip olarak kullanılan gerçek nesnedir Myconstructure.prototypeiçin sadece bir plan olduğunu __proto__, kaydedilir ve protoype olarak kullanılan gerçek nesneye infact. Bu nedenle myobject.prototype, gerçek nesnenin bir özelliği olmaz çünkü yapıcı işlevi tarafından myobject.__proto__neye benzemesi gerektiğini belirlemek için kullanılan geçici bir şeydir .
Alex_Nabu

9
__proto__Bir nesnenin özelliğinin, nesnenin yapıcı işlevinin prototypeözelliğine bir işaretçi olduğunu söylemek adil midir? yani foo .__ proto__ === foo.constructor.prototype
Niko Bellic

10
@Alex_Nabu Pek değil. newCar.__proto__ IS Car.prototype , bir örneği değil Car.prototype. İken Car.protoype IS bir örneğidir object. Car.prototypeveren bir şey değildir newCarherhangi özelliklerini veya yapıyı, sadece IS sonraki objectIn newCar'ın prototip zinciri. Car.prototypegeçici değildir object. Öyle objectdeğeri olarak ayarlandığını __proto__herhangi bir yeni mülkiyet objects kullanılarak yapılan Carbir olarak constructor. Eğer herhangi bir şeyi bir plan olarak düşünmek istiyorsanız object, Caryeni arabalar için bir plan olarak düşünün object.
seangwright

335

prototypebir Function nesnesinin bir özelliğidir. Bu fonksiyon tarafından inşa edilen nesnelerin prototipidir.

__proto__prototipine işaret eden bir nesnenin dahili özelliğidir. Mevcut standartlar Object.getPrototypeOf(O), fiili standart __proto__daha hızlı olmasına rağmen, eşdeğer bir yöntem sağlar .

instanceofBir işlevin prototypebir nesneyle __proto__zincirini karşılaştırarak ilişkiler bulabilir ve bu ilişkileri değiştirerek kesebilirsiniz prototype.

function Point(x, y) {
    this.x = x;
    this.y = y;
}

var myPoint = new Point();

// the following are all true
myPoint.__proto__ == Point.prototype
myPoint.__proto__.__proto__ == Object.prototype
myPoint instanceof Point;
myPoint instanceof Object;

İşte Pointyapıcı işlevi, yordamsal olarak bir nesne (veri yapısı) oluşturur. myPointtarafından oluşturulan bir nesne olduğu için Point()o Point.prototypezaman kaydedilir myPoint.__proto__.


2
Ayrıca __proto__, bir nesnenin özelliğini değiştirirseniz, prototip aramalarının yapıldığı nesneyi de değiştirir. Örneğin, __proto__bir tür çağrılabilir örnek nesneye sahip olmak için bir yöntem nesnesi işlev olarak ekleyebilirsiniz .
kzh

myPoint .__ proto __. constructor.prototype == Point.prototype
Francisco

@kzh lol bana komik sonuç verdi console.log(obj1.call) // [Function: call] obj1.call()// TypeError: obj1.call bir işlev değil. Yaptığımobj.__proto__ = Function.__proto__
abhisekp

myFn.__proto__ = {foo: 'bar'}
kzh

Sanırım senin fikrin var.
ComicScrip

120

Bir işlev bildirildiğinde prototip özelliği oluşturulur.

Örneğin:

 function Person(dob){
    this.dob = dob
 }; 

Person.prototypeözelliği, yukarıdaki işlevi bildirdikten sonra dahili olarak oluşturulur. Yeni Kişi () kullanılarak oluşturulan Kişi örnekleri tarafından paylaşılan Person.prototype'a birçok özellik eklenebilir.

// adds a new method age to the Person.prototype Object.
Person.prototype.age = function(){return date-dob}; 

Varsayılan Person.prototypeolarak bir Objectdeğişmez olduğunu belirtmek gerekir (gerektiği gibi değiştirilebilir).

Kullanılarak oluşturulan her yönetim ortamının işaret new Person()eden bir __proto__özelliği vardır Person.prototype. Bu, belirli bir nesnenin bir özelliğini bulmak için hareket etmek için kullanılan zincirdir.

var person1 = new Person(somedate);
var person2 = new Person(somedate);

2 örneklerini oluşturur Person, bu 2 nesneler çağırabilir ageyöntemi Person.prototypeolarak person1.age, person2.age.

Sorunuzun yukarıdaki resimde, bunu göremiyorsun Foobir olduğunu Function Objectve bu nedenle bir sahip __proto__bağlantısını Function.prototypesırayla bir örneği olup Objectve bir sahiptir __proto__bağlantısını Object.prototype. Burada ile proto bağlantı uçları __proto__içinde Object.prototypehiç işaret null.

Herhangi bir nesne, bağlı olduğu gibi kendi proto zincirindeki tüm özelliklere erişebilir __proto__, böylece prototip palet mirasını oluşturur.

__proto__prototip zincirine erişmenin standart bir yolu değil, standart ama benzer bir yaklaşım kullanmaktır Object.getPrototypeOf(obj).

instanceofOperatör için aşağıdaki kod daha iyi bir anlayış sağlar:

object instanceofClass operatörü true, bir nesne bir Class örneği olduğunda, daha özel Class.prototypeolarak o nesnenin proto zincirinde bulunursa, nesne bu Class'ın bir örneğidir.

function instanceOf(Func){
  var obj = this;
  while(obj !== null){
    if(Object.getPrototypeOf(obj) === Func.prototype)
      return true;
    obj = Object.getPrototypeOf(obj);
  }
  return false;
}      

Yukarıdaki yöntem şöyle denilebilir: instanceOf.call(object, Class)nesne Class örneğiyse true değerini döndürür.


2
prototypeNesnenin neden ilk başta dahili olarak yaratıldığını merak ediyordum. Fonksiyon nesnesinin kendisine statik yöntemler atanabilir. örneğin function f(a){this.a = a}; f.increment = function(){return ++this.a}? Neden bu şekilde metodları prototypenesneye eklemek için seçilmiyordu? f.__proto__ = gG temel sınıfsa, bu işe yarar .
abhisekp

Belki de prototypeişlev oluşturucu nesnesinde yalnızca özel işlev yapıcı özellikleri saklanabildiği için nesne paylaşım için seçilmiştir.
abhisekp

1
Aslında, bu bir karışıklık instanceofolacaktır çünkü özellik kaldırılırsa ({}) instanceof Function === trueprototipler arasında ayrım yapmanın bir yolu olmayacağı için sonuçlanır prototype.
abhisekp

@abhisekp Bununla ne demek istersiniz: "f .__ proto__ = g burada g temel sınıfsa işe yarar." Bunun anlamadığım bir anlamı varsa bilmiyorum, ancak özellikleri ve yöntemleri bu şekilde ekleyecekseniz, newbir örnek oluşturmak için anahtar kelimeyi kullandığınızda , özellikler ve yöntemler kopyalanmaz bitmiş.
doubleOrt

66

Bunu düşünmenin güzel bir yolu ...

prototypeconstructor()fonksiyonlar tarafından kullanılır . Gerçekten böyle bir şey olarak adlandırılmış olmalıydı "prototypeToInstall", çünkü bu böyle.

ve __proto__bir nesne üzerindeki "kurulu prototip" (söz konusu constructor()fonksiyondan nesne üzerine yaratılmış / kurulmuş )


2
Onu iptal ettim, ama belki de aşağı oy nedeni, "prototip yapıcı () işlevleri tarafından kullanılıyor" ifadesinin, yapıcı olmayan işlevler yokmuş gibi gelebileceğiydi, ancak durum böyle değil, ancak şu anda bizim odak noktamız da değil. yeni ile çağrılırsa her fonksiyon potansiyel bir kurucu olduğunu not edebilirsiniz ...
yoel halb

2
Lütfen " constructor()işlevler" ile karışıklık olabileceğinden, " işlevler" i "yapıcı işlevler" olarak değiştirin __proto__.constructor(). Bir newanahtar kelime kullanıldığında __proto __. Yapıcısı aslında çağrılmadığından bunu önemli buluyorum .
Alexander Gonchiy

1
" Prototip (yapıcı () işlevleri tarafından kullanılır) " ifadesi önemli bir gerçeğin sadece bir kısmını anlatır, ancak bunu okurların bütün gerçek olduğunu düşünmeye yönlendirecek şekilde anlattı. prototip , gelecekte bu işlevin nasıl çağrılacağından bağımsız olarak, yeni anahtar sözcükle veya yeni anahtar sözcük olmadan, Javascript'teki her işlev bildirimi için dahili olarak oluşturulur ; bildirilen bir işlevin prototipi bir nesne değişmezine işaret eder.
Yiling

62

Açıklamak için bir işlev oluşturalım

 function a (name) {
  this.name = name;
 }

JavaScript kodu yürütüldüğünde, ekler prototypeözelliğini a, prototypeözelliği kendisine, iki özelliğe sahip bir amacıdır:

  1. constructor
  2. __proto__

Öyleyse yaptığımız zaman

a.prototype geri döner

     constructor: a  // function definition
    __proto__: Object

Gördüğünüz gibi constructor, işlevin akendisinden başka bir şey yok ve JavaScript'in __proto__kök düzeyine işaret ediyor Object.

Anahtar kelime aile fonksiyon kullandığımızda ne olacağını görelim new.

var b = new a ('JavaScript');

JavaScript bu kodu çalıştırdığında 4 şey yapar:

  1. Yeni bir nesne, boş bir nesne yaratır // {}
  2. Bu oluşturur __proto__üzerinde bve işaret yapar a.prototypeSob.__proto__ === a.prototype
  3. Yeni oluşturulan nesne ile a.prototype.constructor(işlev a# 1'de oluşturulan) bağlamı (bu) olarak yürütülür (işlev tanımı ), bu nedenle name'JavaScript' (eklenen this) olarak iletilen özellik yeni oluşturulan nesneye eklenir.
  4. Yeni oluşturulan nesneyi döndürür (1. adımda yaratılır), böylece var byeni oluşturulan nesneye atanır.

Şimdi ekleyip a.prototype.car = "BMW"yaparsak b.car, "BMW" çıktısı görünür.

Bunun nedeni, JavaScript'in carmülk aradığı bu kodu çalıştırması durumunda b, kullanılan JavaScript'i bulamamasıdır b.__proto__(bu, 2. adımda 'a.prototype' yi gösterecek şekilde yapılmıştır) ve carözelliği bulur, böylece "BMW" döndürür.


2
1. constructorgeri dönmez a()! Geri döner a. 2. Javascript'te kök nesneyi __proto__döndürmez Object.prototype.
doubleOrt

1
Bu harika bir cevap!
john-raymon

+1, aslında hangi prototipin IS olduğunu (iki özelliğe sahip bir nesne) ve Javascript'in her bir kod parçasını nasıl yürüttüğünü açıklamak için en iyi cevaptır. Bu bilgi şaşırtıcı derecede zor.
java-addict301

53

Prototip VS. __proto__ VS. [[Prototip]]

Bir işlev oluştururken, prototip adlı bir özellik nesnesi otomatik olarak oluşturulur (siz kendiniz oluşturmadınız) ve işlev nesnesine (the constructor) eklenir .
Not : Bu yeni prototip nesnesi aynı zamanda yerel JavaScript Nesnesini işaret eder veya dahili-özel bağlantıya sahiptir.

Misal:

function Foo () {
    this.name = 'John Doe';
}

// Foo has an object property called prototype.
// prototype was created automatically when we declared the function Foo.
Foo.hasOwnProperty('prototype'); // true

// Now, we can assign properties and methods to it:
Foo.prototype.myName = function () {
    return 'My name is ' + this.name;
}

Anahtar kelimeyi Fookullanarak yeni bir nesne newoluşturursanız, temelde (diğer şeylerin yanı sıra) daha önce tartıştığımız işlevin prototipine dahili veya özel bir bağlantıya sahip yeni bir nesne oluşturursunuz Foo:

var b = new Foo();

b.[[Prototype]] === Foo.prototype  // true


Bu işlevin nesnesine çift bağlantı prototip veya adil adı verilen özel bağlantı [[Prototype]]. Birçok tarayıcı bize bunun için halka açık bir bağlantı sağlıyor __proto__!

Daha spesifik olmak gerekirse, __proto__aslında yerel JavaScript Nesnesine ait bir alıcı işlevidir . Bu ne iç-özel prototip bağlantı döndürür thisbağlayıcıdır (getiri [[Prototype]]arasında b):

b.__proto__ === Foo.prototype // true

Başlangıçta , dahili özel bağlantıyı almak için getPrototypeOf yöntemini ECMAScript5de kullanabileceğinizi belirtmek gerekir:

Object.getPrototypeOf(b) === b.__proto__ // true


NOT: Bu yanıt yeni nesneler ya da yeni kurucular yaratma tüm süreci kapsayacak niyetinde, ancak yardım için daha iyidir anlamayan __proto__, prototypeve [[Prototype]]ve nasıl çalıştığını.


2
@Taurus, başlığa tıklayın, ECMAScript şartname belgesine götürür. Çok daha ayrıntılı olarak açıklayan bölüm 9'a (Sıradan ve Egzotik Nesne Davranışları) bakın.
Lior Elrom

Ben burada bazı hata olduğunu düşünüyorum: _ Fonksiyon prototip iç veya özel bağlantısı olan yeni bir nesne Foo_ Yani: fonksiyon Foo prototip iç veya özel bağlantısı olan yeni bir nesne ?
Koray Tugay

1
Teşekkürler @KorayTugay! Evet, yanlış yazdım :) +1
Lior Elrom

30

Yukarıdaki harika cevaplara ek olarak biraz netleştirmek için:

function Person(name){
    this.name = name
 }; 

var eve = new Person("Eve");

eve.__proto__ == Person.prototype //true

eve.prototype  //undefined

Örnekleri var __proto__ , sınıflar var prototip .


12

JavaScript'te, bir işlev yapıcı olarak kullanılabilir. Bu, yeni anahtar kelimeyi kullanarak onlardan nesne oluşturabileceğimiz anlamına gelir. Her yapıcı işlevi, onlarla zincirlenmiş yerleşik bir nesne ile birlikte gelir. Bu yerleşik nesneye prototip denir.Instances of a constructor function use __proto__ to access the prototype property of its constructor function.

prototip diyagramı

  1. Önce bir yapıcı oluşturuldu: function Foo(){}. Açıkçası, Foo sadece başka bir işlevdir. Ancak yeni anahtar kelimeyle ondan bir nesne oluşturabiliriz. Bu yüzden ona yapıcı işlevi diyoruz

  2. Her işlevin, prototip özelliği adı verilen benzersiz bir özelliği vardır. Yani, Yapıcı işlevi Foo, prototipine işaret eden bir prototip özelliğine sahiptir, yani Foo.prototype(resme bakın).

  3. Yapıcı işlevlerin kendileri, [[İşlev]] yapıcı olarak adlandırılan bir sistem yapıcısının bir örneği olan bir işlevdir. Yani bunun function Foo[[İşlev]] yapıcısı tarafından inşa edildiğini söyleyebiliriz . Yani, __proto__bizim ait Foo functionolan onun yapıcı, prototip irade noktası Function.prototype.

  4. Function.prototypekendisi denilen başka bir sistem kurucusundan yapılan bir nesneden başka bir şey değildir [[Object]]. Yani, [[Object]]kurucusudur Function.prototype. Yani, biz söyleyebiliriz Function.prototypeörneğidir [[Object]]. Yani __proto__bir Function.prototypepuana Object.prototype.

  5. Object.prototypeprototip zincirinde duran son kişidir. Yani inşa edilmedi. Sistemde zaten var. Yani __proto__işaret ediyor null.

  6. Şimdi örneklerine geliyoruz Foo. Kullanarak bir örnek oluşturduğumuzda, örneği new Foo()olan yeni bir nesne oluşturur Foo. Bu Foo, bu örneklerin kurucusu demektir . Burada iki örnek oluşturduk (x ve y). __proto__x ve y bu nedenle işaret eder Foo.prototype.


Açık olmak gerekirse: örneklerin .prototype özelliği yoktur? Sadece yapıcı işlevi doğru mu? ... Yani bir örnek ve yapıcı işlevi arasındaki fark şudur: yapıcı işlevlerinin her ikisi de 1. proto 2. .prototype nesnesine sahipken, örnekler sadece .__ proto__ özelliğine sahiptir ... doğru?
Shaz

@Shaz haklısın. örnekleri , yapıcı işlevlerinin prototip özelliğine erişmek için kendi protokollerini kullanır .
AL-zami

Ama neden yazarken neden böyle: var car = Object.create (Vehicle); car .__ proto__ = Araç Alacaksınız AMA yine Vehicle.prototype'yi gösteren bir car.prototype özelliği mi alıyorsunuz?
Shaz

@ shaz durumu görselleştirebilmem için bir jsfiddle sağlayabilir misiniz?
AL-zami

1
burada car.prototype kalıtsal bir özelliktir. araba, 'prototip' özelliğini araç işlevinden devralır. yani car.prototype === Vehicle.prototype. "prototip" özelliği araçtaki bir özelliktir. araba prototip zincirinden erişebilir. Umarım bu karışıklığınızı
giderir

8

Özet:

__proto__Bir nesnenin özellik eşleştiren bir özelliktir prototypenesnenin yapıcı işlevinin. Başka bir deyişle:

instance.__proto__ === constructor.prototype // true

Bu, prototypebir nesnenin zincirini oluşturmak için kullanılır . prototypeZincir bir nesne üzerinde özellikleri için bir arama bir mekanizmadır. Bir nesnenin özelliğine erişilirse, JavaScript önce nesnenin kendisine bakar. Mülk orada bulunmazsa, protochainbulunana kadar (ya da çıkmadan) sonuna kadar tırmanacaktır.

Misal:

function Person (name, city) {
  this.name = name;
}

Person.prototype.age = 25;

const willem = new Person('Willem');

console.log(willem.__proto__ === Person.prototype); // the __proto__ property on the instance refers to the prototype of the constructor

console.log(willem.age); // 25 doesn't find it at willem object but is present at prototype
console.log(willem.__proto__.age); // now we are directly accessing the prototype of the Person function 

İlk günlük sonuçlarımız true, bunun nedeni, belirtildiği gibi __proto__, kurucu tarafından oluşturulan örneğin prototypeözelliğinin kurucunun özelliğine işaret etmesidir. Unutmayın, JavaScript'te işlevler aynı zamanda Nesnelerdir. Nesneler özelliklere sahip olabilir ve herhangi bir işlevin varsayılan özelliği prototip adı verilen bir özelliktir.

Daha sonra, bu işlev yapıcı işlevi olarak kullanıldığında, ondan başlatılan nesne adlı bir özellik alır __proto__. Ve bu __proto__özellik prototype, yapıcı işlevinin özelliğini ifade eder (varsayılan olarak her işlevin sahip olduğu).

Bu neden faydalı?

JavaScript 'prototypal mirası'Objects olarak adlandırılan özellikleri ararken bir mekanizmaya sahiptir , temel olarak yaptığı şey:

  • İlk olarak, özelliğin Object'in üzerinde olup olmadığı kontrol edilir. Öyleyse, bu özellik döndürülür.
  • Mülk nesnenin kendisinde bulunmuyorsa, 'protokolü tırmanacaktır'. Temel olarak __proto__özellik tarafından atıfta bulunulan nesneye bakar . Burada, özelliğin başvurduğu nesne üzerinde kullanılabilir olup olmadığını denetler __proto__.
  • Özellik __proto__nesnenin üzerinde değilse, nesneye kadar __proto__zincire tırmanacaktır Object.
  • Özelliği nesnenin ve prototypezincirinin hiçbir yerinde bulamazsa, geri döner undefined.

Örneğin:

function Person (name) {
  this.name = name;
}

let mySelf = new Person('Willem');

console.log(mySelf.__proto__ === Person.prototype);

console.log(mySelf.__proto__.__proto__ === Object.prototype);


7

JS'yi bilmiyorum prototipini öğreniyorum : bu & Nesne Prototipleri , altındaki tasarımı anlamak ve çok fazla yanlış anlaşılmayı açıklamak için harika bir kitap (bu yüzden miras ve benzeri şeyleri kullanmaktan kaçınmaya çalışıyorum instanceof).

Ama insanların burada sorduğu soruların aynısı var. Birkaç cevap gerçekten yararlı ve aydınlatıcı. Ayrıca anlayışlarımı paylaşmak isterim.


Prototip nedir?

JavaScript'teki nesneler, spesifikasyonda belirtilen [[Prototype]]başka bir nesneye referans olan dahili bir özelliğe sahiptir. Hemen hemen tüm nesnelere, nulloluşturuldukları sırada bu özellik için bir değer verilmez .

Bir nesnenin prototipi nasıl alınır?

yoluyla __proto__veyaObject.getPrototypeOf

var a = { name: "wendi" };
a.__proto__ === Object.prototype // true
Object.getPrototypeOf(a) === Object.prototype // true

function Foo() {};
var b = new Foo();
b.__proto__ === Foo.prototype
b.__proto__.__proto__ === Object.prototype

Nedir prototype?

prototypeotomatik olarak bir fonksiyonun özel bir özelliği olarak yaratılan ve delegeleme (miras) zincirini, yani prototip zincirini oluşturmak için kullanılan bir nesnedir .

Biz bir işlev oluşturduğunuzda a, prototypeotomatik olarak özel bir özelliği olarak oluşturulur ave olarak işlev kodunu kaydeder constructortarihinde adlı prototype.

function Foo() {};
Foo.prototype // Object {constructor: function}
Foo.prototype.constructor === Foo // true

Bu özelliği bir işlev nesnesinin özelliklerini (yöntemler dahil) depolamak için bir yer olarak düşünmek isterim. Bu da JS fayda fonksiyonları gibi tanımlanır sebebi bu Array.prototype.forEach(), Function.prototype.bind(),Object.prototype.toString().

Neden bir fonksiyonun özelliğini vurgulamak gerekir ?

{}.prototype // undefined;
(function(){}).prototype // Object {constructor: function}

// The example above shows object does not have the prototype property.
// But we have Object.prototype, which implies an interesting fact that
typeof Object === "function"
var obj = new Object();

Yani, Arary, Function, Objecttüm fonksiyonlar bulunmaktadır. Bunun JS hakkındaki izlenimi yenilediğini itiraf etmeliyim. İşlevlerin JS'de birinci sınıf vatandaş olduğunu biliyorum, ancak işlevler üzerine kurulu gibi görünüyor.

Arasındaki fark nedir __proto__ve prototype?

__proto__bir başvuru , kendi özelliğine başvurmak için her nesne üzerinde çalışır [[Prototype]].

prototypeotomatik olarak bir işlevin özel bir özelliği olarak oluşturulan ve bir işlev nesnesinin özelliklerini (yöntemler dahil) depolamak için kullanılan bir nesnedir.

Bu ikisiyle, prototip zincirini zihinsel olarak haritalayabiliriz. Bu resimde gösterildiği gibi:

function Foo() {}
var b = new Foo();

b.__proto__ === Foo.prototype // true
Foo.__proto__ === Function.prototype // true
Function.prototype.__proto__ === Object.prototype // true

7

 JavaScript prototipi ile __prototype__ karşılaştırması

'use strict'
function A() {}
var a = new A();
class B extends A {}
var b = new B();
console.log('====='); // =====
console.log(B.__proto__ === A); // true
console.log(B.prototype.__proto__ === A.prototype); // true
console.log(b.__proto__ === B.prototype); // true
console.log(a.__proto__ === A.prototype); // true
console.log(A.__proto__ === Function.__proto__); // true
console.log(Object.__proto__ === Function.__proto__); // true
console.log(Object.prototype === Function.__proto__.__proto__); // true
console.log(Object.prototype.__proto__ === null); // true

JavaScript'te, Her nesnenin (işlev de nesnedir!) Bir __proto__özelliği vardır, özellik prototipine başvurur.

newİşleci yeni bir nesne oluşturmak için yapıcı ile birlikte kullandığımızda, yeni nesnenin __proto__özelliği yapıcı prototypeözelliğiyle ayarlanır , daha sonra yapıcı yeni nesne tarafından çağrılır, bu işlemde "bu" yeni nesneye bir başvuru olur yapıcı kapsamında, nihayet yeni nesneyi döndürün.

Yapıcı prototipi __proto__mülkiyettir, Yapıcı'nın prototypeözelliği newoperatör ile çalışmaktır .

Yapıcı bir işlev olmalıdır, ancak işlev prototypeözelliği olsa bile her zaman yapıcı değildir .

Prototip zinciri aslında, __proto__prototipine başvurmak için nesnenin özelliğidir ve prototipin prototipine başvurmak için prototipin __proto__özelliğidir ve bu nedenle, Object'in prototipinin __proto__null değerine gönderme özelliğine başvuruluncaya kadar devam eder .

Örneğin:

console.log(a.constructor === A); // true
// "a" don't have constructor,
// so it reference to A.prototype by its ``__proto__`` property,
// and found constructor is reference to A

[[Prototype]]ve __proto__mülkiyet aslında aynı şeydir.

Bir şeyin prototipini almak için Object'in getPrototypeOf yöntemini kullanabiliriz.

console.log(Object.getPrototypeOf(a) === a.__proto__); // true

Yazdığımız herhangi bir işlev, işleçle bir nesne oluşturmak için kullanılabilir new, bu nedenle bu işlevlerden herhangi biri yapıcı olabilir.


6

Anlamanın iyi bir yolu:

var foo = {}

/* 
foo.constructor is Object, so foo.constructor.prototype is actually 
Object.prototype; Object.prototype in return is what foo.__proto__ links to. 
*/
console.log(foo.constructor.prototype === foo.__proto__);
// this proves what the above comment proclaims: Both statements evaluate to true.
console.log(foo.__proto__ === Object.prototype);
console.log(foo.constructor.prototype === Object.prototype);

Yalnızca IE11 __proto__desteklendikten sonra . Bu sürümden önce, IE9 gibi, constructoralmak için kullanabilirsiniz __proto__.


Sadece başka bir şekilde yazacağım: foo .__ proto__ === foo.constructor.prototype
epeleg

6

prototip

prototip bir Fonksiyonun özelliğidir. Yeni anahtar kelimeyle bu (yapıcı) işlevini kullanarak nesne oluşturma planıdır.

__proto__arama zincirinde yöntemleri, özellikleri çözmek için kullanılır. bir nesne oluşturulduğunda (yeni anahtar kelimeyle yapıcı işlevi kullanılarak), __proto__(Constructor) Function.prototype olarak ayarlanır

function Robot(name) {
    this.name = name;
}
var robot = new Robot();

// the following are true   
robot.__proto__ == Robot.prototype
robot.__proto__.__proto__ == Object.prototype

İşte karışıklığı gidermek için (hayali) açıklamam:

İşlevle ilişkili hayali bir sınıf (plan / coockie kesici) olduğunu hayal edin. Bu hayali sınıf, nesneleri somutlaştırmak için kullanılır. prototypebu hayali sınıfa bir şeyler eklemek için genişletme mekanizmasıdır (C # veya Swift Uzantısında genişletme yöntemi).

function Robot(name) {
    this.name = name;
}

Yukarıdaki gibi düşünülebilir:

// imaginary class
class Robot extends Object{

    static prototype = Robot.class  
    // Robot.prototype is the way to add things to Robot class
    // since Robot extends Object, therefore Robot.prototype.__proto__ == Object.prototype

    var __proto__;

    var name = "";

    // constructor
    function Robot(name) {

        this.__proto__ = prototype;
        prototype = undefined;

        this.name = name;
    }

} 

Yani,

var robot = new Robot();

robot.__proto__ == Robot.prototype
robot.prototype == undefined
robot.__proto__.__proto__ == Object.prototype

Şimdi Robot'a yöntem ekleniyor prototype:

Robot.prototype.move(x, y) = function(x, y){ Robot.position.x = x; Robot.position.y = y};
// Robot.prototype.move(x, y) ===(imagining)===> Robot.class.move(x, y)

Yukarıdakiler Robot sınıfının bir uzantısı olarak düşünülebilir:

// Swift way of extention
extension Robot{
    function move(x, y){    
        Robot.position.x = x; Robot.position.y = y
    }
}

Hangi sırayla,

// imaginary class
class Robot{

    static prototype = Robot.class // Robot.prototype way to extend Robot class
    var __proto__;

    var name = "";

    // constructor
    function Robot(name) {

        this.__proto__ = prototype;
        prototype = undefined;

        this.name = name;
    }

    // added by prototype (as like C# extension method)
    function move(x, y){ 
        Robot.position.x = x; Robot.position.y = y
    };
}

hala __proto__prototip için daha tutarlı isimler düşünüyor . belki prototip ve miras?
Dmitry

Ben söyleyebilirim, prototype& __proto__her ikisi de kaçınılmalıdır. Şimdi dersimiz var ve OOP'u seviyorum.
Hassan Tareq

sorun şu ki, sınıf nispeten yeni ve microsoft JScript (C üzerinde çalışırken ve her zaman orada olan hızlı ve kirli bir komut dosyası motoruna ihtiyaç duyulduğunda güzel) ve nashorn javascript (hepsi ile birlikte geliyor) gibi gerçekten uygun motorlar tarafından desteklenmiyor. jjs altında yeni Java kurulumları ve Java'yı sürekli olarak yeniden derlemeniz gerekmeyen saf dinamik bir ortama yerleştirmenin güzel bir yoludur). Mesele şu ki, sınıf şeker olsaydı, bir sorun olmazdı, ama değil, eski js versiyonlarında onlarsız imkansız olan şeyleri sunuyor. "İşlev" i genişletmek gibi.
Dmitry

Sonunda destek alacağız. Ben arka uç geliştirici değilim, bu yüzden sorunları yok, nadiren js kod.
Hassan Tareq

ve statik üyelerin ebeveyn tarafından yeni / statik üyeler ekleyerek çocuk tarafından fark edileceği şekilde miras alınır (ki bu, Object.assign / __ proto __ / getPrototypeOf sunmayan JScript'te yapmanın bir yolunu düşünemiyorum, böylece kök Object.prototype taklit etmek zorundayım)
Dmitry

4

Basitçe söylemek gerekirse:

> var a = 1
undefined
> a.__proto__
[Number: 0]
> Number.prototype
[Number: 0]
> Number.prototype === a.__proto__
true

Bu özellik, X türündeki nesnelerin somutlaştırılmasından SONRA X.prototipine özellikler eklemenize izin verir ve Javascript motorunun prototip zincirini yukarı kaldırmak için kullandığı __proto__ başvurusu aracılığıyla bu yeni özelliklere erişmeye devam eder.


4

Prototip veya Object.prototype , bir nesne değişmezinin özelliğidir. Prototip zinciri boyunca daha fazla özellik veya yöntem eklemek için geçersiz kılabileceğiniz Object prototip nesnesini temsil eder .

__proto__ , erişildiği bir nesnenin dahili prototipini ortaya çıkaran bir erişimci özelliğidir (get ve set işlevi).

Referanslar:

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype
  2. http://www.w3schools.com/js/js_object_prototypes.asp

  3. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto


Object.prototypebir nesne değişmezinin özelliği değil, {}.prototypetanımsız döndürme çıktıları almaya çalışıyor ; ancak, bunlara erişilir {}.__proto__, bu da geri döner Object.prototype.
doubleOrt

3

Biliyorum, geç kaldım ama basitleştirmeye çalışayım.

Diyelim ki bir fonksiyon var

    function Foo(message){

         this.message = message ; 
     };

     console.log(Foo.prototype);

Foo fonksiyonunun bağlı bir prototip nesnesi olacaktır. Dolayısıyla, JavaScript'te bir işlev oluşturduğumuzda, ona her zaman bağlı bir prototip nesnesi vardır.

Şimdi devam edelim ve Foo işlevini kullanarak iki nesne oluşturalım.

    var a = new Foo("a");
    var b = new Foo("b");
    console.log(a.message);
    console.log(b.message);
  1. Şimdi iki nesne var, nesne a ve nesne b. Her ikisi de yapıcı Foo kullanılarak oluşturulur. Unutmayın yapıcı burada sadece bir kelime.
  2. A ve b nesnelerinin her ikisi de message özelliğinin bir kopyasına sahiptir.
  3. Bu iki a ve b nesnesi, yapıcı Foo'nun prototip nesnesiyle bağlantılıdır.
  4. A ve b nesnelerinde , tüm tarayıcılarda proto özelliğini kullanarak Foo prototipine erişebiliriz ve IE'de Object.getPrototypeOf (a) veya Object.getPrototypeOf (b) kullanabiliriz

Şimdi, Foo.prototip, a. proto ve b. proto hepsi aynı nesneyi belirtir.

    b.__proto__ === Object.getPrototypeOf(a);
    a.__proto__ ===  Foo.prototype;
    a.constructor.prototype  === a.__proto__;

yukarıdakilerin hepsi doğru dönecekti.

Bildiğimiz gibi, JavaScript'te özellikler dinamik olarak eklenebilir. Nesneye özellik ekleyebiliriz

    Foo.prototype.Greet = function(){

         console.log(this.message);
    }
    a.Greet();//a
    b.Greet();//b
    a.constructor.prototype.Greet();//undefined 

Gördüğünüz gibi, Foo.prototype'e Greet () yöntemini ekledik ancak a ve b'de veya Foo kullanılarak oluşturulan herhangi bir nesnede erişilebilir.

A.Greet () yürütülürken, JavaScript önce bir özellik listesinde nesnede selamlar. Görmediklerine günü, o kadar gidecek proto bir zinciri. A'dan beri. proto ve Foo.prototype aynı nesnedir, JavaScript Greet () yöntemini bulur ve çalıştırır.

Umarım, şimdi prototip ve proto biraz basitleştirilmiştir.


3

Açıklayıcı örnek:

function Dog(){}
Dog.prototype.bark = "woof"

let myPuppie = new Dog()

şimdi, myPupppie Dog.prototype __proto__işaret özelliği vardır.

> myPuppie.__proto__
>> {bark: "woof", constructor: ƒ}

ancak myPuppie bir prototip özelliğine sahip DEĞİLDİR.

> myPuppie.prototype
>> undefined

Yani, __proto__mypuppie taşımaktadır referans bu nesne örneğini oluşturmak için kullanılan yapıcı fonksiyonunun .prototype özelliğine (ve geçerli myPuppie nesne buna ilişki "delegeler" vardır __proto__myPuppie ait .prototype mülkiyet beri (sadece yokken nesne), ayarlamadık).

MPJ burada iyi bir açıklama: proto vs prototip - JavaScript Nesne Oluşturma


3

Kendime aşağıdaki kod snippet'i temsil eden küçük bir çizim yaptım:

var Cat = function() {}
var tom = new Cat()

__Proto__ ve prototipi anlama

Klasik bir OO arka planım var, bu yüzden hiyerarşiyi bu şekilde temsil etmek yardımcı oldu. Bu diyagramı okumanıza yardımcı olmak için görüntüdeki dikdörtgenlere JavaScript nesneleri gibi davranın. Ve evet, fonksiyonlar aynı zamanda nesnelerdir. ;)

JavaScript'teki nesnelerin özellikleri vardır ve __proto__bunlardan yalnızca biridir.

Bu özelliğin arkasındaki fikir, (miras) hiyerarşisinde ata nesnesine işaret etmektir.

JavaScript'teki kök nesne Object.prototypeve diğer tüm nesneler bunun nesnesidir . __proto__Kök nesnesinin özelliğidir nullmiras zincirin ucunu temsil eden.

Bunun prototypebir işlev özelliği olduğunu fark edeceksiniz . Catbir işlevdir, aynı zamanda Functionve Object(yerel) işlevlerdir. tombir işlev değildir, bu nedenle bu özelliğe sahip değildir.

Bu özelliğin arkasındaki fikir, yapıda kullanılacak bir nesneyi, yani newoperatörü bu işlevde çağırdığınızda işaret etmektir .

Prototip nesnelerinin (sarı dikdörtgenler) constructor, ilgili işlev nesnesini gösteren başka bir özelliğe sahip olduğunu unutmayın . Kısalık nedenleriyle bu tasvir edilmedi.

Aslında, tomnesneyi ile new Cat()oluşturduğumuzda, oluşturulan nesne , yapıcı işlevinin nesnesine __proto__ayarlanan özelliğe sahip olacaktır prototype.

Sonunda, bu şema ile biraz oynayalım. Aşağıdaki ifadeler doğrudur:

  • tom.__proto__özelliği ile aynı nesneyi gösterir Cat.prototype.

  • Cat.__proto__Function.prototypenesneye işaret eder , tıpkı beğen Function.__proto__ve Object.__proto__yap.

  • Cat.prototype.__proto__ve tom.__proto__.__proto__aynı nesneyi işaret ediyor Object.prototype.

Şerefe!


Çok iyi açıkladı!
StackOverflow UI

@theshinylight, tom.__proto__ve Cat.prototypeson derece eşittir, Yani, tom.__proto__ === Cat.prototype Ve Cat.prototype === tom.__proto__doğrudur. Peki, görüntüdeki okla ne demek istediniz ??
aXuser264

Siyah ok (buna atıfta bulunuyorsanız), nesnenin özelliği dışında özel bir anlamı yoktur. Yani prototypemalıdır Cat(Sorunuzun itibaren) nesne.
theshinylight

2

TANIMLAR

(parantez içindeki sayı () aşağıda yazılı koda bir 'bağlantıdır')

prototype- Aşağıdakilerden oluşan bir nesne:
=> ConstructorFunction.prototypebu yapıcı işlev (1) aracılığıyla yaratılan veya oluşturulacak her bir nesne (4) tarafından erişilebilen bu özelin (5) işlevlerinden (3) (3 )
=> yapıcı işlevinin kendisi (1) )
=> __proto__bu nesnenin (prototip nesnesi)

__proto__(dandor proto?) - belirli bir yapıcı işlevi (1) aracılığıyla oluşturulan herhangi bir nesne (2) ARASINDA VE bu yapıcı THAT'ın prototip nesnesinin özellikleri (5), oluşturulan her nesnenin (2) prototipin işlevlerine erişmesine izin verir ve yöntemler (4) ( __proto__varsayılan olarak JS'deki her bir nesneye dahil edilmiştir)

KOD AÇIKLAMA

1.

    function Person (name, age) {
        this.name = name;
        this.age = age;} 

2.

    var John = new Person(‘John’, 37);
    // John is an object

3.

    Person.prototype.getOlder = function() {
        this.age++;
    }
    // getOlder is a key that has a value of the function

4.

    John.getOlder();

5.

    Person.prototype;

1

4. sınıf açıklamasını deneyeceğim:

Her şey çok basit. A prototype, bir şeyin nasıl inşa edilmesi gerektiğine bir örnektir. Yani:

  • Ben functionve benimkine benzer yeni nesneler inşa ediyorumprototype

  • Ben bir objectve __proto__örnek olarak benim kullanılarak inşa edildi

kanıt :

function Foo() { }

var bar = new Foo()

// `bar` is constructed from how Foo knows to construct objects
bar.__proto__ === Foo.prototype // => true

// bar is an instance - it does not know how to create objects
bar.prototype // => undefined

1
Hayır, ne ne prototypede __proto__herhangi bir zamanda herhangi bir nesne oluşturmak için bir plan olarak kullanılmaz. Bu bulanık classsözdizimi ve selefleri tarafından sunulan bir efsanedir . Yanıt yazısının söylediği gibi, sadece arama zinciri için ve kullanılan ile prototypetanımlanması durumunda (bu, benim de dahil olmak üzere birçok kullanıcıyı şaşırtan klas gibi bir mekanizmanın bir parçasıdır) kullanılır.constructornew
Christof Kälin

İlk nokta "Ben bir
Nitin Jadhav

1

Oluşturduğunuz her işlevin adlı bir özelliği vardır prototypeve ömrünü boş bir nesne olarak başlatır. Bu özelliği yapıcı işlevi olarak yani 'yeni' anahtar sözcüğü ile kullanana kadar bu özellik işe yaramaz.

Bu genellikle __proto__bir nesnenin özelliğiyle karıştırılır . Bazıları karışabilir ve bunun dışında prototypebir nesnenin özelliği onlara bir nesnenin proto kodunu verebilir. Ancak durum böyle değil. prototype, __proto__bir işlev yapıcısından oluşturulan bir nesnenin elde edilmesi için kullanılır .

Yukarıdaki örnekte:

function Person(name){
    this.name = name
}; 

var eve = new Person("Eve");

console.log(eve.__proto__ == Person.prototype) // true
// this is exactly what prototype does, made Person.prototype equal to eve.__proto__

Umarım mantıklıdır.


1
prototype__proto__bir nesnenin oluşturulmasında kullanılmaz . __proto__, erişildiğinde yalnızca prototypenesneye bir başvuru sağlar .
doubleOrt

1

__proto__Statik yöntemler için kullanmaya ne dersiniz ?

function Foo(name){
  this.name = name
  Foo.__proto__.collection.push(this)
  Foo.__proto__.count++

}

Foo.__proto__.count=0
Foo.__proto__.collection=[]

var bar = new Foo('bar')
var baz = new Foo('baz')

Foo.count;//2
Foo.collection // [{...}, {...}]
bar.count // undefined

Tam olarak bu yüzden " JavaScript'te __proto__VS. " yeprototype bir cevap ?
Andreas

iyi ya da ne Foo.collection.push (bu) Foo.count ++
Selva Ganapathi

1

(function(){ 
      let a = function(){console.log(this.b)};
      a.prototype.b = 1;
      a.__proto__.b = 2;
      let q = new a();
      console.log(a.b);
      console.log(q.b) 
    })()

Anlamak için bu kodu deneyin


1

Protypal zincirleme için kullanılan tek bir nesne vardır. Bu nesnenin açık bir şekilde bir adı ve değeri vardır: __proto__adı ve prototypedeğeri. Bu kadar.

kavramayı daha da kolaylaştırmak için, bu yazının üstündeki şemaya bakın (dmitry soshnikov diyagramı), asla __proto__başka bir şeye puan bulamazsınız.prototype değeri .

Gist şudur: __proto__prototypal nesnesine başvuran addır ve prototypegerçek prototypal nesnesidir.

Şöyle demek:

let x = {name: 'john'};

xnesne adıdır (işaretçi) ve {name: 'john'}gerçek nesnedir (veri değeri).

NOT: Bu sadece yüksek düzeyde nasıl ilişkili olduğuna dair oldukça basitleştirilmiş bir ipucu.

Güncelleme: İşte daha iyi örnek için basit bir somut javascript örneği:

let x = new String("testing") // Or any other javascript object you want to create

Object.getPrototypeOf(x) === x.__proto__; // true

Ne zaman bu araçlar Object.getPrototypeOf(x)bize gerçek değerini alır x(onun prototip), tam olarak ne __proto__ait xişaret ediyor. Dolayısıyla __proto__gerçekten de prototipine işaret ediyor x. Böylece __proto__referanslar x(işaretçisi x) ve prototypedeğerix (prototipinin) .

Umarım şimdi biraz açıktır.


1

Bu, prototip mirasını anlamak isteyen herkes için çok önemli bir sorudur. Anladığım kadarıyla, işlev tanımına göre prototip nesnesine sahip olduğundan, bir işlevden yeni bir nesne oluşturulduğunda prototip varsayılan olarak atanır:

function protofoo(){
}
var protofoo1 = new protofoo();
console.log(protofoo.prototype.toString()); //[object Object]

Yeni olmayan sıradan bir nesne yarattığımızda, yani açıkça bir işlevden, prototipi yoktur, ancak prototip atanabilen boş bir protokolü vardır.

var foo={
  check: 10
};
console.log(foo.__proto__); // empty
console.log(bar.prototype); //  TypeError
foo.__proto__ = protofoo1; // assigned
console.log(foo.__proto__); //protofoo

Bir nesneyi açıkça bağlamak için Object.create öğesini kullanabiliriz.

// we can create `bar` and link it to `foo`
var bar = Object.create( foo );
bar.fooprops= "We checking prototypes";
console.log(bar.__proto__); // "foo"
console.log(bar.fooprops); // "We checking prototypes"
console.log(bar.check); // 10 is delegated to `foo`

0

__proto__yapısına nokta prototypeve bir yapıcı işlevi örneğin: function human(){}sahip prototypeile ortak olan __proto__yapıcı işlevinin yeni örneği. Daha ayrıntılı bir okuma burada


@Derick Daniel: Buna neden oy verdiğinizden emin değilim ama yaptığınız düzenleme iletmeye çalıştığım değildi. Daha fazla boşluk için daha fazla düzenledi :).
Jyoti Duhan

Jyoti, cevabını aşağı oylamadım, başkası yaptı, ben sadece düzenledim :)
Freelancer

0

Gibi bu haklı belirtti

__proto__yöntemler vb. çözümlemek için arama zincirinde kullanılan gerçek nesnedir. prototip, __proto__yeni bir nesne oluşturduğunuzda oluşturmak için kullanılan nesnedir:

( new Foo ).__proto__ === Foo.prototype;
( new Foo ).prototype === undefined;

Ayrıca şunu not edebiliriz: __proto__ işlev yapıcısı kullanılarak oluşturulan bir nesnenin özelliğinin, prototipin işaret ettiği bellek konumuna işaret özelliğinin, ilgili özelliği ile .

Yapıcı işlevinin prototipinin bellek konumunu değiştirirsek, __proto__türetilmiş nesne yine de orijinal adres alanını göstermeye devam eder. Bu nedenle, ortak özellik miras zincirinde kullanılabilir hale getirmek için , yeniden başlatmak yerine (bellek adresini değiştirecek) yapıcı işlev prototipine her zaman özellik ekleyin .

Aşağıdaki örneği düşünün:

function Human(){
    this.speed = 25;
}

var himansh = new Human();

Human.prototype.showSpeed = function(){
    return this.speed;
}

himansh.__proto__ === Human.prototype;  //true
himansh.showSpeed();    //25

//now re-initialzing the Human.prototype aka changing its memory location
Human.prototype = {lhs: 2, rhs:3}

//himansh.__proto__ will still continue to point towards the same original memory location. 

himansh.__proto__ === Human.prototype;  //false
himansh.showSpeed();    //25

-1

benim anlayışım: __proto__ ve prototipin hepsi prototip zincir tekniği için kullanılıyor. fark, alt çizgi ile adlandırılan işlevler (__proto__ gibi) açıkça çağrılan geliştiricileri hedeflemez. başka bir deyişle, sadece miras gibi bazı mekanizmalar içindir. Bunlar 'arka uç'tur. ancak alt çizgi olmadan adlandırılan işlevler açıkça çağrılmak üzere tasarlanmıştır, bunlar 'ön uç'tur.


3
Daha vardır __proto__ve prototypesadece adlandırma kuralı yerine,. Aynı nesneyi gösterebilir veya göstermeyebilirler. @Zyklus cevabına bakınız.
demisx

1
@demisx'in elbette doğru olduğunu söylediniz, ancak benim görüşüm, işlevsellik kontrastını ortaya koyan isim farkı.
Beicai

"Anlayışınıza göre", özellikle de daha önce başka iyi cevaplar verildiğinde belirtmek yeterli değildir ...
ProfNandaa

-3

!!! BU DÜNYANIN EN İYİ AÇIKLAMASI !!!!!

var q = {}
var prototype = {prop: 11}

q.prop // undefined
q.__proto__ = prototype
q.prop // 11

fonksiyon yapıcıları javascript motoru q.__proto__ = prototypeyazdığımızda bunu otomatik olarak çağırır new Classve __proto__pervane setineClass.prototype

function Class(){}
Class.prototype = {prop: 999} // set prototype as we need, before call new

var q = new Class() // q.__proto__ = Class.prototype
q.prop // 999

Zevk almak %)

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.