“未捕获的TypeError:未定义不是函数”-初学者Backbone.js应用程序

问题描述 投票:38回答:2

我正在用主干建立一个非常简单的应用程序,但出现错误。

Uncaught TypeError: undefined is not a function example_app.js:7
ExampleApp.initialize example_app.js:7
(anonymous function)

这是Chrome Inspector中显示错误的位置(初始化文件-example_app.js):

var ExampleApp = {
  Models: {},
  Collections: {},
  Views: {},
  Routers: {},
  initialize: function() {
    var tasks = new ExampleApp.Collections.Tasks(data.tasks);
    new ExampleApp.Routers.Tasks({ tasks: tasks });
    Backbone.history.start();
  }
};

这是我的任务index.haml文件

- content_for :javascript do
  - javascript_tag do
    ExampleApp.initialize({ tasks: #{raw @tasks.to_json} });

= yield :javascript

模型/ task.js

var Task = Backbone.Model.extend({});

collections / tasks.js

var Tasks = Backbone.Collection.extend({
    model: Task,
    url: '/tasks'
});

路由器/tasks.js

ExampleApp.Routers.Tasks = Backbone.Router.extend({
    routes: {
        "": "index"
    },

    index: function() {
        alert('test');
        // var view = new ExampleApp.Views.TaskIndex({ collection: ExampleApp.tasks });
        // $('body').html(view.render().$el);
    }
});

这是我正在调用所有文件的证明(我认为):

<script src="/assets/jquery.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery_ujs.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery-ui.js?body=1" type="text/javascript"></script>
<script src="/assets/underscore.js?body=1" type="text/javascript"></script>
<script src="/assets/backbone.js?body=1" type="text/javascript"></script>
<script src="/assets/backbone-support/support.js?body=1" type="text/javascript"></script>
<script src="/assets/backbone-support/composite_view.js?body=1" type="text/javascript"></script>
<script src="/assets/backbone-support/swapping_router.js?body=1" type="text/javascript"></script>
<script src="/assets/backbone-support.js?body=1" type="text/javascript"></script>
<script src="/assets/example_app.js?body=1" type="text/javascript"></script>
<script src="/assets/easing.js?body=1" type="text/javascript"></script>
<script src="/assets/modernizr.js?body=1" type="text/javascript"></script>
<script src="/assets/models/task.js?body=1" type="text/javascript"></script>
<script src="/assets/collections/tasks.js?body=1" type="text/javascript"></script>
<script src="/assets/views/task_view.js?body=1" type="text/javascript"></script>
<script src="/assets/views/tasks.js?body=1" type="text/javascript"></script>
<script src="/assets/views/tasks_index.js?body=1" type="text/javascript"></script>
<script src="/assets/routers/tasks.js?body=1" type="text/javascript"></script>
<script src="/assets/tasks/index.js?body=1" type="text/javascript"></script>
<script src="/assets/tasks/task.js?body=1" type="text/javascript"></script>
<script src="/assets/application.js?body=1" type="text/javascript"></script>

任何想法都很棒。谢谢!

javascript ruby-on-rails ruby-on-rails-3 backbone.js
2个回答
81
投票

未捕获的TypeError:未定义不是函数example_app.js:7

此错误消息讲述了整个故事。在这行上,您正在尝试执行一个函数。但是,无论执行什么都不是函数!而是undefined

那么example_app.js 7行上是什么?看起来像这样:

var tasks = new ExampleApp.Collections.Tasks(data.tasks);

在该行上仅运行一个功能。我们发现了问题! ExampleApp.Collections.Tasksundefined

所以让我们看一下它的声明位置:

var Tasks = Backbone.Collection.extend({
    model: Task,
    url: '/tasks'
});

如果这是该集合的所有代码,则根本原因就在这里。您将构造函数分配给名为Tasks的全局变量。但是您永远不要将其添加到ExampleApp.Collections对象中,此位置以后您希望它位于。

将此更改为此,我打赌你会很好。

ExampleApp.Collections.Tasks = Backbone.Collection.extend({
    model: Task,
    url: '/tasks'
});

看看正确的名称和行号在弄清楚这一点上有多重要?永远不要将错误视为二进制文件(它起作用或不起作用)。而是读取错误,在大多数情况下,错误消息本身为您提供了寻找真实问题所需的关键线索。


在Javascript中,当您执行函数时,其评估方式如下:

expression.that('returns').aFunctionObject(); // js
execute -> expression.that('returns').aFunctionObject // what the JS engine does

该表达式可能很复杂。因此,当您看到undefined is not a function时,表示表达式未返回函数对象。因此,您必须弄清楚为什么要尝试执行的不是函数。

在这种情况下,是因为您没有在您认为应该做的地方放东西。


0
投票

我在以下示例中发生了相同的错误-

async.waterfall([function(waterCB) {
    waterCB(null);
}, function(**inputArray**, waterCB) {
    waterCB(null);
}], function(waterErr, waterResult) {
    console.log('Done');
});

在上述瀑布函数中,我在瀑布第二函数中接受inputArray参数。但是这个inputArray没有在waterCB的瀑布第一函数中传递。

检查功能参数,下面是一个正确的示例。

async.waterfall([function(waterCB) {
    waterCB(null, **inputArray**);
}, function(**inputArray**, waterCB) {
    waterCB(null);
}], function(waterErr, waterResult) {
    console.log('Done');
});

谢谢

© www.soinside.com 2019 - 2024. All rights reserved.