Javascript 类型错误:未定义不是构造函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38928987/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
TypeError: undefined is not a constructor
提问by Adam Plocher
I'm very new to Angular and I'm trying to figure much of this out still. I'm writing some tests using Angular 1.5.8 which I generated from the Yeoman Generator.
我对 Angular 很陌生,我仍在努力解决大部分问题。我正在使用从 Yeoman Generator 生成的 Angular 1.5.8 编写一些测试。
Specifically, I'm trying to figure out how to manipulate $httpBackend results (I'm not sure if that's important or not)...
具体来说,我试图弄清楚如何操作 $httpBackend 结果(我不确定这是否重要)...
In my app.js file I have the following code:
在我的 app.js 文件中,我有以下代码:
.run(['$rootScope', '$location', 'breadcrumbService', function ($rootScope, $location, breadcrumbService) {
$rootScope.$on('$viewContentLoaded', function () {
jQuery('html, body').animate({scrollTop: 0}, 200);
});
$rootScope.isEditMode = false;
$rootScope.$on('$stateChangeSuccess', function () {
// ------------ this next line is failing -----------
$rootScope.isEditMode = $location.path().toLowerCase().endsWith('/edit') || $location.path().toLowerCase().endsWith('/new');
});
$rootScope.parseJson = function (value) {
return angular.fromJson(value);
};
$rootScope.bc = breadcrumbService;
$rootScope.title = "";
}])
The line about halfway down (where I added the comment) is failing. Specifically, the endsWith
function is failing (toLower is fine), with this error:
大约一半的行(我添加评论的地方)失败了。具体来说,该endsWith
函数失败(toLower 很好),并出现以下错误:
PhantomJS 2.1.1 (Windows 8 0.0.0) Service: breadcrumbService should return breadcrumb label in json format FAILED
TypeError: undefined is not a constructor (evaluating '$location.path().toLowerCase().endsWith('/edit')') in app/scripts/app.js (line 44)
app/scripts/app.js:44:72
$broadcast@bower_components/angular/angular.js:18005:33
bower_components/angular-ui-router/release/angular-ui-router.js:3353:32
processQueue@bower_components/angular/angular.js:16383:30
bower_components/angular/angular.js:16399:39
$eval@bower_components/angular/angular.js:17682:28
$digest@bower_components/angular/angular.js:17495:36
$apply@bower_components/angular/angular.js:17790:31
done@bower_components/angular/angular.js:11831:53
handleResponse@bower_components/angular-mocks/angular-mocks.js:1368:17
flush@bower_components/angular-mocks/angular-mocks.js:1808:26
test/spec/services/breadcrumbservice.js:33:27
invoke@bower_components/angular/angular.js:4718:24
workFn@bower_components/angular-mocks/angular-mocks.js:3085:26
Here is my test code (some junk modified from different examples - just trying to get it to work):
这是我的测试代码(从不同的示例中修改了一些垃圾 - 只是想让它工作):
'use strict';
describe('Service: breadcrumbService', function () {
// load the service's module
beforeEach(module('myModule'));
var $httpBackend, $rootScope, createController, authRequestHandler;
beforeEach(inject(function($injector) {
$httpBackend = $injector.get('$httpBackend');
console.log('Is null? '+ ($httpBackend == null));
$httpBackend.whenGET(/views\/.*/).respond(200, [{}, {}, {}]);
authRequestHandler = $httpBackend.when('GET', '/api/v1/SiteStagings')
.respond({userId: 'userX'}, {'A-Token': 'xxx'});
// Get hold of a scope (i.e. the root scope)
$rootScope = $injector.get('$rootScope');
$httpBackend.flush();
}));
// instantiate service
var breadcrumbService;
beforeEach(inject(function (_breadcrumbService_) {
breadcrumbService = _breadcrumbService_;
}));
it('svc should exist', function () {
expect(!!breadcrumbService).toBe(true);
});
it('should return breadcrumb label in json format', function () {
var result = breadcrumbService.getFromCache('site', 'SiteGroupStagings', 46, 'SiteGroupDesc');
console.log(result);
expect(!!result).toBe(true);
});
});
I don't doubt that I'm doing something wrong here, I just can't quite understand what it is. What does this error really mean and why does it not like my call to endsWith
?
我不怀疑我在这里做错了什么,我只是不太明白它是什么。这个错误的真正含义是什么,为什么它不喜欢我的调用endsWith
?
Thanks
谢谢
回答by dgraf
undefined is not a constructor
undefined 不是构造函数
is an error message PhantomJS displays when you tried to call a function that is not defined. It depends on the version of ECMAScript which your PhantomJS supports. So as you said it works fine in Chrome, because this browser supports the function you are using in test. In order to fix your problem and still be able to use PhantomJS you can replace the "unknown to PhantomJS" function with your own.
是当您尝试调用未定义的函数时 PhantomJS 显示的错误消息。这取决于您的 PhantomJS 支持的 ECMAScript 版本。所以正如你所说,它在 Chrome 中运行良好,因为这个浏览器支持你在测试中使用的功能。为了解决您的问题并仍然能够使用 PhantomJS,您可以用您自己的函数替换“PhantomJS 未知”函数。
回答by Hula_Zell
I was getting TypeError: undefined is not a constructor
error using the includes()
method. The includes()
and endsWith()
methods are new in ECMAScript 2015, and are not supported in Internet Explorer, and evidently not by PhantomJS.
我正在TypeError: undefined is not a constructor
用错误includes()
的方法。该includes()
和endsWith()
方法在2015年的ECMAScript新,并在Internet Explorer中不支持,看样子不是PhantomJS。
There is a chance your end user may be using Internet Explorer. In which case, you may want to use the fully supported indexOf()
method instead of includes()
or endsWith()
您的最终用户可能正在使用 Internet Explorer。在这种情况下,您可能希望使用完全支持的indexOf()
方法而不是includes()
或endsWith()
For example, in my case, everything worked great in chrome, but my tests were failing on the line:
例如,就我而言,在 chrome 中一切正常,但我的测试失败了:
if (item.name.includes('contents'))
I changed to using the indexOf() method instead:
我改为使用 indexOf() 方法:
if (item.name.indexOf('contents') !== -1)
And then I was no longer getting the error
然后我不再收到错误
TypeError: undefined is not a constructor
类型错误:未定义不是构造函数
回答by Adam Plocher
I debated whether or not to post this as an answer or just an edit to my question, but I guess it's my answer (for now):
我争论过是否将此作为答案发布或只是对我的问题的编辑,但我想这是我的答案(目前):
It seems the problem is related to PhantomJS. As soon as I changed the engine to Chrome in the karma.conf.js file, those tests passed.
问题似乎与 PhantomJS 有关。一旦我在 karma.conf.js 文件中将引擎更改为 Chrome,这些测试就通过了。
I still don't know what that error message is supposed to mean and why it wasn't working with PhantomJS, but at least I'm now able to continue.
我仍然不知道该错误消息的含义以及为什么它不能与 PhantomJS 一起使用,但至少我现在可以继续了。
Here are the modifications to my karma.conf.js (in case anyone is curious):
以下是对我的 karma.conf.js 的修改(以防有人好奇):
browsers: [
//'PhantomJS',
'Chrome'
],
// Which plugins to enable
plugins: [
'karma-chrome-launcher',
//'karma-phantomjs-launcher',
'karma-jasmine'
],
Btw - I did notice that endsWith
is new to ECMAScript6 (I was thinking it was older), but WebStorm shows that it's referencing a helper function in angular-ui-grid. I spent quite a while messing with the files
array in the karma.conf.js file in an attempt to see if the ui-grid dependency was loading too late or something. In every test, it worked fine in Chrome but not PhantomJS. I still have no idea why.
顺便说一句 - 我确实注意到endsWith
ECMAScript6 是新的(我认为它更旧),但 WebStorm 显示它正在引用 angular-ui-grid 中的辅助函数。我花了很files
长时间弄乱karma.conf.js 文件中的数组,试图查看 ui-grid 依赖项是否加载太晚或什么的。在每个测试中,它在 Chrome 中运行良好,但在 PhantomJS 中运行良好。我仍然不知道为什么。
回答by Martin
In My Case: Cyclic Dependencies Causing:
在我的情况下:循环依赖导致:
PhantomJS 2.1.1 (Windows 8 0.0.0) ERROR TypeError: undefined is not a constructor (evaluating '(0, _actions.prefix)('SET_USER_INPUT_PHONE_NUMBER')') at undefined:12
PhantomJS 2.1.1 (Windows 8 0.0.0) 错误类型错误:未定义不是构造函数(评估 '(0,_actions.prefix)('SET_USER_INPUT_PHONE_NUMBER')')在未定义:12
I got the same error after I added imports in my javascript production code (ES6 syntax compiled with babel/webpack). The changes were fine when a production build of the application was loaded in chrome but running the tests with phantomJS produced the error. In my case the added imports created cyclic dependencies.
在我的 javascript 生产代码(用 babel/webpack 编译的 ES6 语法)中添加导入后,我遇到了同样的错误。当应用程序的生产版本在 chrome 中加载时,更改很好,但使用 phantomJS 运行测试会产生错误。在我的情况下,添加的导入创建了循环依赖项。
I'm dropping this here for future reference (I stumbled upon the same problem a few weeks ago and don't want to scratch my head again in another couple of weeks) and for others that google the same error.
我把它放在这里以供将来参考(几周前我偶然发现了同样的问题,不想再过几周再次挠头)和其他人用谷歌搜索同样的错误。
回答by Alok
I faced similar error with PhantomJS:
我在使用 PhantomJS 时遇到了类似的错误:
For me the error was the way in which I was creating a spy object for my service.
对我来说,错误是我为我的服务创建间谍对象的方式。
Error on line in code file new Service.getData(param1, param2)
代码文件中的行错误 new Service.getData(param1, param2)
Fix in test file: jasmine.createSpyObj('Service',['getData'])
在测试文件中修复: jasmine.createSpyObj('Service',['getData'])
What is was missing was adding ['getData]
while creating spyObj
缺少的是['getData]
在创建 spyObj时添加