2013-05-24 3 views
5

Ниже приведен код сброса ошибки TypeError: myObj.prototype is undefined. Может ли кто-нибудь объяснить мне, почему?Почему этот код JS недействителен?

Почему нет prototype для new Object() & Объектные литералы, как указано ниже?

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

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

Если это недопустимый подход, то как я могу это достичь?

+5

Это должно быть просто 'myObj.c =" foo ";' – epascarello

+0

Вы можете получить прототип из экземпляра с Object.getPrototypeOf: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/getPrototypeOf, хотя в этом случае вы, вероятно, не захотите. –

+0

Взгляните на [Eloquent Javascript] (http://eloquentjavascript.net/chapter8.html). –

ответ

10

В более ранних версиях EcmaScript вы не могли напрямую получить доступ к прототипу объектов; свойство prototype существовало только для функций, и оно вступает в игру, когда они используются в качестве конструкторов. Таким образом, вы можете сделать это:

// 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 реализации Object.getPrototypeOf, что означает, что вы можете сделать это:

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

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

Однако, вы должны быть осторожны! Если вы сделаете это, то все объекты, которые существуют сейчас, и все объекты, созданные в будущем, наследуют свойство c через свою прототипную цепочку!

Это потому, что myObj имеет тип Object и прототип Object наследуется все, что является объектом любого типа. Это приводит к:

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

Нет! «x.prototype» НЕ «прототип x». – georg

+0

@ thg435: Я не уверен, что понимаю вашу точку зрения, не могли бы вы прояснить? – Jon

+0

Конечно - когда вы пишете «someObj.prototype» в javascript, вы не получаете доступ к прототипу объекта. 'x.prototype' полностью отличается от фактического прототипа x - он просто имеет запутанное имя. – georg

1

вы должны сначала объявить пользовательский объект, как это:

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

, то вы можете добавить свойство «с» для этого объекта следующим образом

myObj.prototype.c = "c"; 

, как вы можете видеть здесь http://jsfiddle.net/gwaqm/ свойство c успешно установлен.

0

Если вы хотите добавить гр свойства после создания объекта вы можете сделать

myObj.c = 'This is c'; 
0

объекты наследуют свойства прототипа их конструктор, а не их собственный прототип.

Вы можете использовать myObj.constructor.prototype. Но вы не должны этого делать, потому что ({}). Constructor == Object. Таким образом, вы модифицируете прототип этого объекта, который вы модифицируете прототипом всех объектов.

Чтобы создать объект с определенным использованием прототипа:

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

ИЛИ

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

Вы не должны использовать __proto__, потому что это плохой дизайн и "Нестандартные" (См. https://developer.mozilla.org/de/docs/JavaScript/Reference/Global_Objects/Object) Вы можете использовать Object.getPrototypeOf (obj), хотя

0

Вы не можете получить доступ к прототипу объекта через prototype - это будет просто свойство, называемое прототипом. Вы можете получить доступ к прототип через __proto__

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

myObj.__proto__.c= 3; 

var test = {}; 

test.c //-> yields 3 

Правильный (совместим со стандартом) способ, однако было бы использовать либо (не ECMA-Standard!):

Object.getPrototypeOf(myObj) 

или

myObj.constructor.prototype 
+0

Я не могу понять ваш ответ. confusing.not clear – SivaRajini

+0

@Siva, что смущает об этом? – Christoph

0

В первом примере вы использовали Object Literal Notation для определения объекта с двумя свойствами: a и b.

prototype связан с объектом constructor. Если вы хотите получить доступ прототип объекта, вы сначала начать с помощью функции конструктора:

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

Затем обратитесь к своему прототипу:

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

Таким образом, все объекты, которые в конечном итоге разделяют MyCLASS прототип наследует члена pa.

Смежные вопросы