2012-04-11 8 views
51

ich definieren, ein Objekt wie folgt aus:Javascript „Not a Constructor“ Ausnahme beim Erstellen von Objekten

function Project(Attributes, ProjectWidth, ProjectHeight) 
{ 
    this.ProjectHeight = ProjectHeight; 
    this.ProjectWidth = ProjectWidth; 
    this.ProjectScale = this.GetProjectScale(); 
    this.Attributes = Attributes; 

    this.currentLayout = ''; 

    this.CreateLayoutArray = function() 
    {....} 
} 

ich dann versuchen, zu erstellen und zu Beispiel wie folgt aus:

var newProj = new Project(a,b,c); 

Aber diese execption geworfen wird :

Project is not a constructor 

Was könnte falsch sein? Ich habe viel gegoogelt, kann aber immer noch nicht herausfinden, was ich falsch mache.

+1

Aus Neugier, den Browser zu geben, dass „Projekt ist kein Konstruktor“ Nachricht? –

+12

Als nicht verwandter Seitenknoten empfehlen allgemeine JavaScript-Stilrichtlinien das Starten eines Variablenbezeichners mit einem Großbuchstaben nur, wenn es ein Konstruktor ist: "Projekt" ist in Ordnung, aber das führende Kapital in "ProjectHeight" legt mir nahe, dass es auch ein sein soll Konstrukteur. Wenn Sie stattdessen "projectHeight" verwenden, wird Ihr Code für andere besser lesbar sein. (Wenn andere Poster richtig sind und Sie an anderer Stelle eine Projektvariable definiert haben, wird die Verwendung der Regel "Großbuchstaben - für Konstruktoren - nur" Ihnen ersparen, diesen Fehler erneut zu machen.) – apsillers

+0

@DaggNabbit Opera does (12.15) – PeerBr

Antwort

58

Der in der Frage angegebene Code kann diesen Fehler nicht generieren, da Project keine benutzerdefinierte Funktion/kein gültiger Konstruktor ist.

function x(a,b,c){} 
new x(1,2,3);    // produces no errors 

Sie haben wahrscheinlich so etwas getan:

function Project(a,b,c) {} 
Project = {};    // or possibly Project = new Project 
new Project(1,2,3);   // -> TypeError: Project is not a constructor 

Variablendeklarationen werden immer vor dem Rest des Codes ausgewertet. So kann diese auch verursacht Probleme sein:

function Project(){} 
function localTest() { 
    new Project(1,2,3); // `Project` points to the local variable, 
         // not the global constructor! 

    //...some noise, causing you to forget that the `Project` constructor was used 
    var Project = 1; // Evaluated first 
} 
+0

In Chrome scheint es zumindest einige Variationen von Nichtfunktions-/Nicht-CTor-bezogenen Nachrichten zu geben. Ihr Beispiel gibt "TypeError: Objekt ist keine Funktion." 'new NodeList' gibt" TypeError: Illegal constructor. " 'new Function.prototype' gibt der OP-Nachricht den nächsten Hinweis:" TypeError: function Empty() {} ist kein Konstruktor. " Interessant, was? –

+0

@RobW: Ich denke in deinem zweiten Beispiel war das lokale "Projekt" * kein * Konstrukteur, oder? – Bergi

+1

@RobW: Ja, aber Ihr Beispiel wird nicht zu einem "no constructor" Fehler führen, wird es nur den falschen verwenden? Ich dachte, du wärst über das Schlüsselwort var (v), das die lokalen vars vor der Ausführung der Funktion initialisiert. – Bergi

17

Ich habe auch gegoogelt um und fand diese Lösung:

Sie haben eine Variable Project irgendwo das keine Funktion ist. Dann wird sich der Operator new darüber beschweren. Versuchen Sie console.log(Project) an der Stelle, wo Sie es als Konstrukteur verwendet hätten, und Sie werden es finden.

31

Eine weitere Ursache dafür können ES6-Pfeilfunktionen sein. Sie können nicht als Konstruktoren verwendet werden.

const f =() => {}; new f(); // This throws "f is not a constructor"

+2

Gibt es einen besonders genannten Grund warum nicht? – Amndeep7

+6

@ Amndeep7 meine Annahme wäre, weil 'new' das konstruierte Objekt als' this' in die Konstruktorfunktion übergibt, aber Pfeilfunktionen immer das 'th' des einschließenden Bereichs haben. – wprl

5

In meinem Fall war ich mit den Prototypen Namen als Objektnamen. Für z.B.

function proto1() 
{} 

var proto1 = new proto1(); 

Es ist ein dummer Fehler war, aber könnte wie mir Hilfe zu jemand sein;)

+0

Nach stundenlangem Debugging war dies die Lösung für mich. Vielen Dank! –

3

für mein Projekt, das Problem erwies sich als eine zirkuläre Referenz durch die require() erstellt werden Anrufe:

Der Grund ist, dass, wenn es versucht, y zu initialisieren, es ein temporäres "y" -Objekt (nicht Klasse, Objekt!) Im Abhängigkeitssystem erzeugt, das irgendwie noch kein Konstruktor ist. Wenn x.js dann fertig definiert ist, kann y weiterhin einen Konstruktor erstellen. Nur, x.js hat einen Fehler darin, wo versucht wird, den Nicht-Konstruktor y zu verwenden.

+0

Vielen Dank für dieses Posting - hatte genau das gleiche Szenario. – Jonah

10

Für mich waren es die Unterschiede zwischen import und auf ES6.

z.

// processor.js 
class Processor { 

} 

export default Processor 

//index.js 
const Processor = require('./processor'); 
const processor = new Processor() //fails with the error 

import Processor from './processor' 
const processor = new Processor() // succeeds 
1

In meinem Fall hatte ich die öffnen und schließen Klammern am Ende der Definition der Funktion vergessen alle meine Code in der exportierten Modul gewickelt wird. I.e.Ich hatte:

(function() { 
    'use strict'; 

    module.exports.MyClass = class{ 
    ... 
); 

Statt:

(function() { 
    'use strict'; 

    module.exports.MyClass = class{ 
    ... 
)(); 

Der Compiler beschwert sich nicht, aber die Aussage im Importmodul erfordert nicht die Variable sie zugeordnet ist wird, so dass es nicht definiert ist bei der Punkt, den Sie versuchen, es zu konstruieren, und es wird den TypeError: MyClass is not a constructor Fehler geben.

1

Um der @ wprl-Antwort hinzuzufügen, kann die ES6-Objektmethode shorthand, wie die Pfeilfunktionen, auch nicht als Konstruktor verwendet werden.

const o = { 
    a:() => {}, 
    b() {}, 
    c: function() {} 
}; 

const { a, b, c } = o; 

new a(); // throws "a is not a constructor" 
new b(); // throws "b is not a constructor" 
new c(); // works 
1

Ich hatte einen ähnlichen Fehler und mein Problem war, dass der Name und Fall des Variablennamen und Konstruktor Namen identisch waren, die da Javascript, um die beabsichtigte Konstruktor als die neu erstellte Variable interpretiert nicht funktioniert.

Mit anderen Worten:

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

//elsewhere... 

//this is no good! name/case are identical so javascript barfs. 
let project = new project('My Project'); 

Durch einfaches Ändern Fall oder Variablennamen behebt das Problem, aber:

//with a capital 'P' 
function Project(name){ 
    this.name = name; 
} 

//elsewhere... 

//works! class name/case is dissimilar to variable name 
let project = new Project('My Project'); 
0

Es geschieht, weil Sie eine andere Variable "Projekt" genannt verwendet haben, müssen in Ihrem Code. So etwas wie var project = {}

Für Sie den Code arbeitet, ändern zu machen, wie folgt:

var project = {} in var project1 = {}

+0

Danke für die Antwort, aber ich sehe nicht wirklich, wie dies etwas bietet, das die anderen Antworten noch nicht angesprochen haben. Wie die [akzeptierte Antwort] (https://stackoverflow.com/a/10107303/2311559) von 2012. – agrm

Verwandte Themen