2012-04-11 59 views
51

我定义的对象是这样的:的Javascript同时创造“不是构造函数”异常物体

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); 

但这execption抛出:

Project is not a constructor 

什么可能是错误的?我搜索了很多,但仍然无法弄清楚我做错了什么。

+1

出于好奇,该浏览器给予该“项目是不是一个构造器”的消息? – 2012-04-11 13:54:51

+12

作为一个不相关的边节点,一般JavaScript风格指南建议仅在构造函数中使用大写字母来启动变量标识符:“Project”没问题,但“ProjectHeight”中的首要资本暗示它也应该是构造函数。如果你使用“projectHeight”代替,你的代码对其他人更易读。 (事实上​​,如果其他海报是正确的,并且你已经在其他地方定义了一个Project变量,那么使用前置 - 大写 - 仅供构造器使用的规则将使你不会再犯这个错误。) – apsillers 2012-04-11 13:55:37

+0

@DaggNabbit Opera does(12.15) – PeerBr 2013-06-20 17:39:48

回答

58

问题中发布的代码无法生成该错误,因为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 

声明变量的代码的其余部分之前始终评估。所以,这也可能是导致问题:

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

至少在Chrome中,似乎有非函数/非ctor相关消息的几种变体。你的例子给出了“TypeError:对象不是一个函数。” '新的NodeList'给出“TypeError:非法的构造函数。” 'new Function.prototype'给出了最接近OP的消息:“TypeError:function Empty(){}不是构造函数。”有趣的,呃? – 2012-04-11 14:03:42

+0

@RobW:我想在你的第二个例子中,本地的“Project”是指*不是*作为构造函数,对吧? – Bergi 2012-04-11 14:08:37

+1

@RobW:是的,但是您的示例不会导致“无构造函数”错误,它只会使用错误的错误?我以为你是关于var关键字的,它在执行函数之前初始化局部范围的变量。 – Bergi 2012-04-11 14:15:39

17

我也用Google搜索了一圈,发现此解决方案:

你有一个变量Project的地方,不是一个函数。然后new运营商会抱怨。尝试console.log(Project)在你将它用作建造者的地方,你会发现它。

31

其他原因可能是ES6箭头功能。它们不能用作构造函数。

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

+2

有没有特别引用的原因,为什么不呢? – Amndeep7 2016-06-13 21:24:33

+6

@ Amndeep7我的猜测是因为'new'将构造对象作为'this'传入构造函数,但箭头函数始终具有封闭作用域的'this'。 – wprl 2016-06-14 20:18:19

5

在我来说,我所用的原型名称作为对象名称。对于例如

function proto1() 
{} 

var proto1 = new proto1(); 

这是一个愚蠢的错误,但可能的帮助,像我;)

+0

经过几个小时的调试,这对我来说就是解决方案。谢谢! – 2017-06-06 17:54:06

3

我的项目,这个问题竟然是)由需要(创建一个循环引用调用:

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的地方有一个错误。

+0

感谢您发表这个 - 只是有这个完全相同的情况。 – Jonah 2017-07-30 01:09:40

10

对我来说,这是ES6上importrequire之间的差异。

E.g.

// 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

在我来说,我在函数包裹我的所有代码导出模块中的定义结束忘了打开和关闭括号。即我:

(function() { 
    'use strict'; 

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

相反的:

(function() { 
    'use strict'; 

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

编译器不抱怨,但进口模块不设置它被赋予变量在需要语句,所以它在不确定的您尝试构建它的这一点,它会给出TypeError: MyClass is not a constructor错误。

1

要添加到@ 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 
1

我有一个类似的错误,我的问题是,名和变量名和构造函数名的情况下是相同的,这是不行的,因为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'); 
0

它正在发生的事情,因为你必须有一个命名为“项目”另一个变量的码。像 var project = {}

东西给你,使代码工作,变化如下:

var project = {}var project1 = {}

+0

感谢您的回答,但我真的不明白这是如何提供其他答案尚未解决的问题。就像2012年的[接受的答案](https://stackoverflow.com/a/10107303/2311559)一样。 – agrm 2017-12-26 18:01:29