2016-08-12 1 views
-1

ich eine Eigenschaft auf eine Funktion geben, und diese Funktion als Konstruktor verwenden, wie folgt aus:Ist diese JavaScript-Eigenschaft eine Instanzeigenschaft oder eine Prototypeigenschaft?

function h(){this.a='abc';} 
h.high='2.0'; 
var hinst=new h(); 
function hasPrototypeProperty(object, name){ 
    return !object.hasOwnProperty(name) && (name in object); 
} 
console.log(h.hasOwnProperty('high')); //true 
console.log(hinst.hasOwnProperty('high'));//false 
console.log(hasPrototypeProperty(hinst, 'high'));//false 
console.log('a' in hinst); //true 
console.log('high' in hinst);//false 
console.log(hinst.prototype.constructor.high); //exception 

Sehr seltsam, in meinem Test, ‚hoch‘ ist weder eine Instanz Eigenschaft

hinst.hasOwnProperty)

oder eine Eigenschaft prototype

hasPrototypeProperty(hinst,'high')

und die letzte Zeile wirft eine Ausnahme zu sagen

TypeError: Cannot read property 'constructor' of undefined

Ich nehme an, ich habe etwas Verständnis auf dem Grundstück, wie könnte 'Hinst' 'High' Eigentum besuchen?

+2

'high' ist Eigentum des Konstruktor, so:' hinst.constructor.high' zurückkehren ' "2.0" sollte'. 'hinst.constructor.hasOwnProperty ('high')' => 'true'. – undefined

Antwort

1

Lassen Sie uns die Dinge ein wenig brechen.

Hier wird eine Konstruktorfunktion erstellt. Sie sind für den Einsatz mit dem Operator new vorgesehen. Eine weit verbreitete Konvention besteht darin, den ersten Buchstaben groß zu schreiben, um diese Absicht sichtbar zu machen.

function H(){ this.a='abc'; } 

Wenn die Konstruktor-Funktion mit new, etwas Ähnliches wie diese aufgerufen wird, geschieht:

(function(){ 
    var o = Object.create(H.prototype); 
    H.apply(o, arguments); 
    return o; 
}()); 

Sie grundsätzlich mit einem neuen Objekt am Ende ({ a: 'abc' }), die von H.prototype Objekt erbt. Das heißt, seine interne [[Prototype]] Eigenschaft weist darauf hin.

H.prototype ist zunächst ein Objekt mit einer einzigen Eigenschaft (constructor, die auf Konstruktorfunktion H zeigt), aber Sie können es frei ersetzen oder erweitern. Das ist, was Sie wahrscheinlich mit dieser Linie tun wollte:

H.high='2.0'; 

Aber stattdessen Sie hinzugefügt, um die Eigenschaft auf die Konstruktorfunktion H (Funktionen sind Objekte auch).

console.log(H.hasOwnProperty('high'));    //true 
console.log((new H()).hasOwnProperty('high'));  //false 
console.log((new H()).hasPrototypeProperty('high')); //false 

Korrigierte Beispiel.

function H(){ this.a='abc'; } 
 
H.prototype.high='2.0'; 
 
var hinst = new H(); 
 
function hasPrototypeProperty(object, name){ 
 
    return !object.hasOwnProperty(name) && (name in object); 
 
} 
 
console.log(H.hasOwnProperty('high'));   //false 
 
console.log(hinst.hasOwnProperty('high'));  //false 
 
console.log(H.prototype.hasOwnProperty('high')); //true 
 
console.log(hasPrototypeProperty(hinst, 'high')); //true 
 
console.log('a' in hinst);      //true 
 
console.log('high' in hinst);      //true 
 
console.log(H.prototype.high);     //2.0 
 
console.log(hinst.high);       //2.0


Inheritance and the prototype chain at MDN

1

Hier ist h ein Objekt vom Typ function, dem Sie eine property mit dem Namen high zugewiesen haben. Es ist also nicht auf Instanz oder Prototyp bezogen.

+0

Immer noch ein bisschen verwirrt, wie könnte ich "hinst" zu "high" Eigentum machen? – Troskyvs

+0

@Troskyvs: Setzen Sie es auf 'h.prototype.high', nicht' h.high'! Instanzen erben vom Prototyp, nicht vom Konstruktor. – Bergi

0

Es gibt einige Verwirrung in Ihrem Code zwischen Konstrukteuren und Prototypen

console.log(inst.prototype.constructor.high); // exception 
console.log(inst.constructor.high); // '2.0' 

weil Ihr Konstruktor nicht Teil der Prototypkette ist.
Wenn Sie definieren Eigenschaften nach der Tat auf Konstrukteuren (die nur Funktionen), dann Sie mit diesem

function h() { 
this.a='abc'; 
} 
h.high='2.0'; 
console.log(h); 
// => { [Function: h] high: '2.0' } 

ein Frankenstein-Funktion-Objekt Monster am Ende.

Verwandte Themen