2012-04-11 68 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