私はこのようなオブジェクトを定義しています:
function Project(Attributes, ProjectWidth, ProjectHeight)
{
this.ProjectHeight = ProjectHeight;
this.ProjectWidth = ProjectWidth;
this.ProjectScale = this.GetProjectScale();
this.Attributes = Attributes;
this.currentLayout = '';
this.CreateLayoutArray = function()
{....}
}
次に、次のようなインスタンスを作成してみます。
var newProj = new Project(a,b,c);
しかし、この実行はスローされます:
Project is not a constructor
何が間違っているのでしょうか?私は多くのことをグーグルで調べましたが、それでも私が間違っていることを理解できません。
Project
はユーザー定義関数/有効なコンストラクターではないため、質問に投稿されたコードはそのエラーを生成できません。
function x(a,b,c){}
new x(1,2,3); // produces no errors
おそらく次のようなことをしたでしょう:
function Project(a,b,c) {}
Project = {}; // or possibly Project = new Project
new Project(1,2,3); // -> TypeError: Project is not a constructor
var
を使用した変数宣言は hoisted であるため、常にコードの残りの前に評価されます。そのため、これも問題を引き起こす可能性があります。
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
}
この追加の原因は、ES2015 矢印関数 である可能性があります。 これらをコンストラクターとして使用することはできません。
const f = () => {};
new f(); // This throws "f is not a constructor"
私にとっては、ES6のimport
とrequire
の違いでした。
例えば。
// 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
私もグーグルで調べて、この解決策を見つけました:
関数ではない場所に変数Project
があります。その後、new
演算子はそれについて文句を言います。それをconstrucotrとして使用するはずの場所でconsole.log(Project)
を試してみてください。
私のプロジェクトでは、この問題はrequire()呼び出しによって作成された循環参照であることが判明しました。
y.js:
var x = require("./x.js");
var y = function() { console.log("result is " + x(); }
module.exports = y;
x.js:
var y = require("./y.js");
var my_y = new y(); // <- TypeError: y is not a constructor
var x = function() { console.log("result is " + my_y; }
module.exports = x;
理由は、yを初期化しようとすると、依存関係システムに一時的な「y」オブジェクト(クラス、オブジェクトではない!)を作成します。次に、x.jsの定義が完了すると、yをコンストラクターにできます。唯一、x.jsには非コンストラクターyを使用しようとするエラーがあります。
私の場合、プロトタイプ名をオブジェクト名として使用していました。たとえば.
function proto1()
{}
var proto1 = new proto1();
それはばかげた間違いでしたが、私のような人の助けになるかもしれません;)
コンストラクターが別のファイルから呼び出される場合、コンストラクターをエクスポートするのを忘れるなどの単純なことを追加したいだけです
module.exports = NAME_OF_CONSTRUCTOR
また、「コンストラクタではない」例外が発生します。
@wprlの答えに追加するために、ES6オブジェクトメソッドの短縮形は、矢印関数のように、コンストラクターとしても使用できません。 ????
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
私の場合は、エクスポートされたモジュール内のすべてのコードをラップする関数の定義の最後にある開いたおよび閉じたパラメーターを忘れていました。つまり私が持っていた:
(function () {
'use strict';
module.exports.MyClass = class{
...
);
の代わりに:
(function () {
'use strict';
module.exports.MyClass = class{
...
)();
コンパイラーは文句を言いませんが、インポートモジュールのrequireステートメントは割り当てられている変数を設定しません。したがって、構築しようとした時点では未定義であり、TypeError: MyClass is not a constructor
エラーが発生します。
これは、コードで「プロジェクト」という名前の別の変数を使用している必要があるために発生しています。 var project = {}
のようなもの
コードを機能させるには、次のように変更します。
var project = {}
をvar project1 = {}
に
同様のエラーが発生し、私の問題は変数名とコンストラクター名の名前と大文字小文字が同一であるということでした。これはjavascriptが意図したコンストラクターを新しく作成された変数として解釈するため機能しません。
言い換えると:
function project(name){
this.name = name;
}
//elsewhere...
//this is no good! name/case are identical so javascript barfs.
let project = new project('My Project');
ただし、単に大文字と小文字または変数名を変更するだけで問題は解決します。
//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');