Javascript'te yeni bir nesnenin prototip özelliği var mı?

Bu akademik değer için tamamen önemsiz bir sveyau:

Yeni bir nesne oluşturursam, şunu yaparak:

var o = { x:5, y:6 };

veya

var o = Object.create({ x:5, y:6 });

o.prototype özelliğini sorguladığımda undefined alırım. Yeni oluşturulan herhangi bir nesnenin otomatik olarak Object.prototype prototipini miras aldığını düşündüm.

Furthermveyae, invoking toString(), (a method of Object.prototype) on this object wveyaks just fine, implying that o does inherit from Object.prototype. So why do I get undefined?

16
@pimvdb Bu yüzden devam ettim ve Object.getPrototypeOf (o) metodunu kullandım: x = Object.getPrototypeOf (o); için (x içinde ilerlet) {console.log (x); } ve bazı gerçekten tuhaf davranışlar alıyorum, her özellik için object nesnesini x ve y yerine alırım. Merakla aynı şeyi yapıyor ama console.log (x [prop]) yapıyoruz 5 ve 6'yı döndürüyor.
katma yazar dkugappi, kaynak
Nesneniz bir örnektir, oysa bir işlev prototype özelliğine sahip yapıcıdır. Bir örneğin prototipini almak istiyorsanız, Object.getPrototypeOf (o) komutunu kullanın.
katma yazar pimvdb, kaynak
@Alex Nabokov: `ile, ör. `test` test değerini verecektir. (Bunları kelimenin tam anlamıyla ifade etmek için, onlardan kaçmak.)
katma yazar pimvdb, kaynak
"O" nesnesinin "prototip" özelliği, çalışma zamanı sisteminin prototip nesnesini bulduğu değil şeklindedir. Bunu takip etmek için dahili özellikler var; hepsi çok kafa karıştırıcı. Soru çok sorulur ve eğer iyi blog mesajlarından birini bulabilirsem konuya bağlarım.
katma yazar Pointy, kaynak

3 cevap

Örnekler ve kurucular arasında bir fark var.

{a: 1} gibi bir nesne oluştururken, Object yapıcısının bir örneğini oluşturursunuz. Object.prototype gerçekten kullanılabilir ve bu prototip içindeki tüm işlevler kullanılabilir:

var o = {a: 1};
o.hasOwnProperty === Object.prototype.hasOwnProperty;//true

Ancak Object.create farklı bir şey yapar. Bir örnek oluşturur (bir nesne), ancak ek bir prototip zinciri ekler:

var o = {a: 1};
var p = Object.create(o);

Zincir olacak:

Object.prototype  -  o  -  p

Bu şu demek:

p.hasOwnProperty === Object.prototype.hasOwnProperty;//true
p.a === o.a;//true

Bir örneğin "altında" prototipini almak için Object.getPrototypeOf komutunu kullanabilirsiniz:

var o = {a: 1};
var p = Object.create(o);

Object.getPrototypeOf(p) === o;//true
Object.getPrototypeOf(o) === Object.prototype;//true

(Önceden, bir örneğin prototipine o .__ proto __ ile erişebilirsiniz, ancak bu kullanımdan kaldırılmıştır.)

Prototip'e aşağıdaki gibi de erişebileceğinizi unutmayın:

o.constructor === Object;//true

Yani:

o.constructor.prototype === Object.prototype//true
o.constructor.prototype === Object.getPrototypeOf(o);//true

Bu Object.create -created nesneler için başarısızdır, çünkü bir kurucu (veya daha doğrusu, yapıcı Object öğesidir ve Object.create öğesine geçirdiğinizden değil. çünkü kurucu işlevi yoktur).

17
katma
Detaylı cevap için teşekkürler. Tam olarak anlamadığım bir şey, o.prototype (yukarıdaki gibi Nesne yapıcısının bir örneğidir) undefined ve Object.getPrototypeOf (o) prototipini döndürür. Onlar teoride aynı şey değiller ve aynı prototip nesnesine işaret ediyorlar mı?
katma yazar dkugappi, kaynak
@Alex Nabokov: Hayır - yapıcıların .prototype ve örneklerinde Object.getPrototypeOf var. Yani o nesnesinde Object.prototype (yapıcı) ve Object.getPrototypeOf (o) (örnek) var. Bu iki aynı şeyi ifade eder.
katma yazar pimvdb, kaynak
"{a: 1} gibi bir nesne oluştururken, Nesne yapıcısının bir örneğini oluşturuyorsunuz" dediniz. "... Object constructor kullanarak yeni bir örnek oluşturuyorsunuz" demek daha doğru olmaz mıydı? Cevabını basmaya çalışmıyorum ama bu darn dili Javascript'i anlamaya çalışıyorum.
katma yazar Ian Durkan, kaynak

Doğrudan bir cevap değil, ama Javascript'te mirasla uğraşan herkesin sahip olması gerektiği bilgisi.

Javascript'te prototip miras, zor bir kavramdır. Şimdiye kadar, boş bir obje yaratılması imkansızdı (boşluğa göre; Yani bu, yeni bir nesne oluşturmanın her zaman orijinal Nesne prototipine bir bağlantıya sahip olduğu anlamına gelir. Bununla birlikte, belirtime göre, bir nesne örneğinin prototip zinciri görünür değildir, ancak bazı satıcılar kendi özel nesne özelliklerini uygulamaya karar vermişlerdir, böylece onu takip edebilirsiniz, ancak üretim kodunda kullanılmaması önerilir.

Aşağıdaki örnek kod, bir nesne örneği oluşturmanın yalnızca iki yolunu gösterir.

var someObject = {};
var otherObject = new Object();
var thirdObject = Object.create({});

Boş kaşlı ayraçlara elle nesne özellikleri eklemeseniz bile, otomatik olarak prototip zinciri eklenir. Aynı şey ikinci örnek için de geçerli. Daha iyi görselleştirmek için bu satırları Chrome konsoluna yazabilir ve ayrıntıları görmek için someObject , otherObject veya thirdObject komutlarını girebilirsiniz. Chrome, ne tür bir devralındığını ve nereden geldiğini görmek için genişletebileceğiniz özel bir __ proto __ mülkü ekleyerek prototip zincirini gösterir. Gibi bir şey yaptıysanız

Object.prototype.sayHello = function() {
  alert('hello');
};

Tüm durumlarda otherObject.sayHello() komutunu çalıştırarak bunu çağırabilirsiniz.

Ancak, son zamanlarda uygulanan bir şey kullanmak (bu nedenle tüm tarayıcılar tarafından desteklenmez), gerçekten gerçekten boş bir nesne örneği oluşturabilirsiniz (Nesnenin kendisinden bile miras almazsınız).

var emptyObject = Object.create(null);

Bunu Chrome konsoluna girdiğinizde ve prototip zincirini görmek için emptyObject 'i genişletdiğinizde, var olmadığını görebilirsiniz. Bu yüzden sayHello işlevini Nesne prototipine uygulasanız bile emptyObject.sayHello() komutunu çağırmak imkansız olur çünkü emptyObject , Nesne prototipi.

Umarım genel fikirle biraz yardımcı olur.

4
katma
+1 Daha önce aşağıdaki gibi yapabilirsiniz: var o = {}; o .__ proto__ = null; ancak yine de kullanımdan kaldırıldı.
katma yazar pimvdb, kaynak
@pimvdb bilgime __ proto __ ne standartlaştırılır ne de tüm tarayıcılar tarafından desteklenir.
katma yazar zatatatata, kaynak

JavaScript'in iki tür nesnesi vardır: işlev nesnesi ve işlev dışı nesne. Kavramsal olarak, tüm nesneler prototipine sahiptir ( PROTOTİP DEĞİL DEĞİL ). Dahili olarak, JavaScript bir nesnenin prototipini [[Prototype]] olarak adlandırır.

Herhangi bir nesneyi (işlev dışı nesne de dahil) almak için iki yaklaşım vardır: [[prototype]]: Object.getPrototypeOf() yöntemi ve __ proto __ özellik. __ proto __ özelliği, birçok tarayıcı ve Node.js. tarafından desteklenmektedir. ECMAScript 6'da standartlaştırılmalıdır.

Yalnızca bir işlev (çağrılabilir) nesne prototype özelliğine sahip. Bu prototip özelliği, işlevin kendi [[prototip]] ile doğrudan ilişkisi olmayan normal bir özelliktir. Bir kurucu olarak kullanıldığında (yeni operatörden sonra), işlevin prototip özelliği yeni oluşturulan bir nesnenin [[Prototip]] 'ına atanır. İşlevsiz bir nesnede, prototype özelliği tanımsızdır. Örneğin,

var objectOne = {x: 5}, objectTwo = Object.create({y: 6});

ObjectOne ve objectTwo öğelerinin ikisi de işlev dışı nesnelerdir, dolayısıyla prototype özelliğine sahip değildirler .

3
katma