2013-05-24 17 views
5

Il codice snipped riportato di seguito genera un errore TypeError: myObj.prototype is undefined. Qualcuno potrebbe spiegarmi perché?Perché questo codice JS non è valido?

Perché non è disponibile lo new Object() & valori letterali degli oggetti come specificato di seguito?

var myObj = { 
    a : "This is a", 
    b : "This is b" 
} 

myObj.prototype.c= "This is c"; // TypeError: myObj.prototype is undefined 

Se questo non è un approccio valido, come posso ottenerlo?

+5

Dovrebbe essere solo 'myObj.c =" foo ";' – epascarello

+0

È possibile ottenere il prototipo da un'istanza con Object.getPrototypeOf: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/getPrototypeOf anche se in questo caso probabilmente non lo si vorrebbe. –

+0

Dai un'occhiata a [Eloquent Javascript] (http://eloquentjavascript.net/chapter8.html). –

risposta

10

Nelle versioni precedenti di EcmaScript non era possibile accedere direttamente al prototipo di oggetti; la proprietà prototype esisteva solo sulle funzioni e entra in gioco quando vengono utilizzate come costruttori. Così si potrebbe fare questo:

// This is the myObj constuctor 
function myObj() { 
    this.a = "This is a"; 
    this.b = "This is b"; 
} 

// Setting a property on the constructor prototype 
// All instances will share this 
myObj.prototype.c= "This is c"; 

// Creating a new object and testing its "c" property 
var obj = new myObj(); 
alert(obj.c); // "This is c" 

Modern browsers attuare Object.getPrototypeOf, il che significa che si può fare questo:

var myObj = { 
    a : "This is a", 
    b : "This is b" 
} 

Object.getPrototypeOf(myObj).c= "This is c"; 

Tuttavia, bisogna stare attenti! Se si esegue questa operazione, quindi tutti gli oggetti che esistono ora e tutti gli oggetti che vengono creati in futuro erediteranno la proprietà c attraverso la loro catena di prototipi!

Questo perché myObj è di tipo Object, e il prototipo di Object viene ereditato da tutto ciò che è un oggetto di qualsiasi tipo. Questo porta a:

var myObj = { 
    a : "This is a", 
    b : "This is b" 
} 

Object.getPrototypeOf(myObj).c= "This is c"; 

var anotherObject = {}; 

alert(anotherObject.c); // "This is c" -- was it expected? 

See it in action.

+0

No! "x.prototype" NON è "il prototipo di x". – georg

+0

@ thg435: non sono sicuro di aver capito il tuo punto, puoi chiarire per favore? – Jon

+0

Certo - quando scrivi "someObj.prototype" in javascript non accedi al prototipo dell'oggetto. 'x.prototype' è completamente diverso dal prototipo reale di x - sembra solo avere un nome confuso. – georg

1

si deve prima dichiarare un oggetto personalizzato come questo:

function myObj(){ 
    this.a = "a"; 
    this.b = "b"; 
} 

poi si può aggiungere la proprietà "c" per quell'oggetto come segue

myObj.prototype.c = "c"; 

come si può vedere qui http://jsfiddle.net/gwaqm/ la proprietà c è stato impostato con successo.

0

Se si vuole aggiungere alla proprietà c dopo la creazione di oggetti che puoi fare

myObj.c = 'This is c'; 
0

oggetti ereditano le proprietà del prototipo del loro costruttore, non loro prototipo.

È possibile utilizzare myObj.constructor.prototype. Ma non dovresti farlo perché ({}). Costruttore == Oggetto. Così si modifica il prototipo di quell'oggetto si modifica il prototipo di tutti gli oggetti.

Per creare un oggetto con un uso specifico prototipo:

//New method 
var proto = ... 
var myObj = Object.create(proto); 

O

//Old method 
var proto = ... 
var constructor = function(){}; 
constructor.prototype = proto; 
var myObj = new constructor(); 

Non si dovrebbe uso __proto__, perché è una cattiva progettazione e "non standard" (Vedi https://developer.mozilla.org/de/docs/JavaScript/Reference/Global_Objects/Object) È possibile utilizzare Object.getPrototypeOf (obj) anche se

0

Non è possibile accedere al prototipo di un oggetto tramite prototype - si tratterebbe semplicemente di una proprietà denominata prototipo. Si potrebbe accedere il prototipo tramite __proto__

var myObj = { 
    a : "This is a", 
    b : "This is b" 
} 

myObj.__proto__.c= 3; 

var test = {}; 

test.c //-> yields 3 

L'(conformi allo standard) modo corretto però sarebbe quello di utilizzare (senza ECMA-standard!):

Object.getPrototypeOf(myObj) 

o

myObj.constructor.prototype 
+0

non riesco a capire la tua risposta. confusion.not clear – SivaRajini

+0

@Siva cosa c'è di confuso a riguardo? – Christoph

0

Nel tuo primo esempio hai usato Object Literal Notation per definire un oggetto con due proprietà: a e b.

prototype è correlato all'oggetto constructor. Se si desidera accedere al prototipo di un oggetto, si inizia con una funzione di costruzione:

function myClass(){ 
    this.a = "This is a"; 
} 

Poi si riferiscono al suo prototipo:

myClass.prototype.pa = "This is prototyped a"; 

Quindi, tutti gli oggetti che alla fine condividono la myClass il prototipo erediterà il membro pa.