JavaScript error: “is not a constructor”

2020-08-13 01:57发布

问题:

I'm using backbone.js along with jquery and underscore.js

Here's some of my code (it doesn't do anything yet). The strange thing is that upon hitting the url "/#users" there isn't an error. The only time the error happens is when I then click to go to a different hash and then click back to go to "/#users". Here's part of my code, with the line that receives the error toward the end Users = new Users(); the error says "Users is not a constructor":

var User = Backbone.Model.extend({
    url: function(){return 'api/user/id/' + this.id;}
});

var Users = Backbone.Collection.extend({
    model: User,
    url: function(){return 'api/users';},
    initialize: function() {
    }
});

var UsersView = Backbone.View.extend({
    initialize: function() {
        this.users = this.options.users;
        this.render();
    },

    render: function() {
        _(this.users).each(function(){
        //  $('#app').append('here');
        });

        var template = _.template($('#usersTemplate').text());

        $(this.el).html(template({users: this.users}));
        $('#app').html(this.el);
    }
});

var UserView = Backbone.View.extend({
    initialize: function() {
        this.user = this.options.user;
        this.render();
    },

    render: function() {

        var template = _.template("hello {{user.name}}");

        $(this.el).html(template({user: this.user.toJSON()}));
        $('#app').html(this.el);
    }
});

var Controller = Backbone.Controller.extend({
    routes: {
        'dashboard' : 'dashboard',
        'users' : 'showusers'
    },

    showuser: function(id) {
        UserList.fetch({
            success: function(){
                new UserView({user: User});
            },
            error: function(){
                alert('an error of sorts');
            }
        });
    },

    showusers: function() {
        Users = new Users();
        Users.fetch({
            success: function(Users) {
                new UsersView({users: Users});
            },
            error: function() {
            }
        });
    },

    dashboard: function() {
        Users = new Users;
        Users.fetch({
            success: function() {
                new UsersView({users: Users});
            },
            error: function() {
            }
        });
    }
});

$(document).ready(function(){
    var ApplicationController = new Controller;
    Backbone.history.start();
});

the accompanying html if you're curious:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Administration Panel</title>

    <!-- Framework -->
    <script src="/javascripts/jquery.min.js"></script>
    <script src="/javascripts/underscore.min.js"></script>
    <script src="/javascripts/backbone.js"></script>

    <!-- Application -->
    <script src="/javascripts/application.js"></script>

    <script id="usersTemplate" type="text/x-underscore-template">
        asdf
    </script>

</head>
<body>

<div>
<a href="#dashboard">Dashboard</a>
<a href="#users">Users</a>
<a href="#products">Products</a>
<a href="#orders">Orders</a>
<a href="#pages">Pages</a>
<a href="#settings">Settings</a>
</div>

<div id="app"></div>

</body>
</html>

回答1:

new can only be used with a Function as the operand.

new {}  // Error: ({}) is not a constructor

Check the type of Users in context: it is not a Function when that exception is raised.

Happy coding


alert(typeof(Users)) ought to do the trick. The result should be "function" to be usable as a constructor. Take note of what it is in the failing case, and see below for a reason.

One problematic scenario (for Users = new Users) may be: an object is constructed from the Function Users and then the object (now not a Function/constructor) is assigned back to Users so the next new Users will go kaboom! (Look in both showusers and dashboard -- is that behavior really intended?)

The 'correct' code is likely: var users = new Users; users.blahblah(...); that is, use a new local variable and do not overwrite the global Users variable/property.


The reason the error is only generated when "going back" to "#foobar" (a Fragment Identifier) is that no new page is actually loaded and thus the JavaScript is not reloaded and the current (now corrupt Users) is being used. kaboom!

Excerpt from Fragment Identifier:

If the targeted element is located in the current document, a user agent may simply focus the targeted element without having to reload it ...



回答2:

I think its Syntax Error

this happened with me when I tried to return anonymous object in my function

 var FalsEextension=false;
 ........
 ........
 return new  { FalsEextension, LargeFile };// wrong Syntax 

and the correct Syntax is

 return { FalsEextension, LargeFile };

and you can use it like this

ObjectName.FalsEextension