Javascript类-调用函数时未定义不是函数

Javascript类-调用函数时未定义不是函数,javascript,class,oop,iife,Javascript,Class,Oop,Iife,我正在尝试用javascript编写OO。这样做有几种不同的方式 我在一些AnglularJ的例子中看到了一些我认为最清楚的东西 可悲的是,我越来越难过了 未定义不是一个函数 调用我的实例的函数时 var MyChooser = (function () { var self = this; var constructor = function (selectBox, previewBox) { this.selectBox = selectBox;

我正在尝试用javascript编写OO。这样做有几种不同的方式

我在一些AnglularJ的例子中看到了一些我认为最清楚的东西

可悲的是,我越来越难过了

未定义不是一个函数

调用我的实例的函数时

var MyChooser = (function () {

    var self = this;
    var constructor = function (selectBox, previewBox) {
        this.selectBox = selectBox;
        this.previewBox = previewBox;
        this.selectBox.change(function () {
            alert(this.value);
        })
    };

    MyChooser.prototype.loadFrames = function () {
        alert("load");
        $.ajax({url: "api.php"}).done(function (data) {
            alert(data);
            //self.frames = data;
        })
    };

    MyChooser.prototype.displayFrame = function (frame) {
        this.previewBox.setAttribute("src", frame.src);
    };

    MyChooser.prototype.invalidateSelectBox = function () {

    };

    return constructor;
});



 var fp = new MyChooser(document.getElementById("frame-select"), document.getElementById("frame-preview"));
            fp.loadFrames();
为什么会出现这个错误

(我还删除了jquery调用,但这不是问题所在)

最后缺少一个
()
,无法使封闭函数成为IIFE

var MyChooser = (function () {

  var constructor = function(select,...stuff){...}

  // Note we're using constructor.prototype rather than MyChooser.prototype
  constructor.prototype.foo = function...
  ...

  return constructor;
}()); // Note the ()
如果没有它,您的
构造函数将不会被分配/返回到
MyChooser
。最后,
MyChooser
是一个返回
constructor
的函数,而不是
constructor
本身。另外,将原型方法更改为指向
constructor
,而不是
MyChooser

此外,所有这些混乱都是由于构造函数及其方法定义被放置在闭包中这一事实造成的,而闭包不是必需的。您可以简单地选择:

function MyChooser(select,...stuff){...}
MyChooser.prototype.moarStuff = function(){...};

...

var fp = new MyChooser(...);
最后缺少一个
()
,使封闭函数成为一个生命

var MyChooser = (function () {

  var constructor = function(select,...stuff){...}

  // Note we're using constructor.prototype rather than MyChooser.prototype
  constructor.prototype.foo = function...
  ...

  return constructor;
}()); // Note the ()
如果没有它,您的
构造函数将不会被分配/返回到
MyChooser
。最后,
MyChooser
是一个返回
constructor
的函数,而不是
constructor
本身。另外,将原型方法更改为指向
constructor
,而不是
MyChooser

此外,所有这些混乱都是由于构造函数及其方法定义被放置在闭包中这一事实造成的,而闭包不是必需的。您可以简单地选择:

function MyChooser(select,...stuff){...}
MyChooser.prototype.moarStuff = function(){...};

...

var fp = new MyChooser(...);
这可以起到以下作用:

 var MyChooser = (function () {
    function MyChooser (p1, p2) {

    }

    MyChooser.prototype.f1 = function () {
        return true;
    };

    return MyChooser 
})();

var thisChooser = new MyChooser(param1, param2);
注意iife,我返回MyChooser而不是构造函数,以及构造函数是如何定义的

这可以工作:

 var MyChooser = (function () {
    function MyChooser (p1, p2) {

    }

    MyChooser.prototype.f1 = function () {
        return true;
    };

    return MyChooser 
})();

var thisChooser = new MyChooser(param1, param2);

注意iife,我返回MyChooser而不是构造函数,以及构造函数是如何定义的

既然您提到您正在用Javascript进行OO,那么让我向您介绍一种更好的用Javascript创建对象的方法,这种方法更干净、更易于阅读、更安全。我是在读《Javascript:好的部分》这本好书的时候学会的

下面是创建对象的方法

var constructor = function (spec) {
    var that;

    var privateFunc = function () {};
    var privateVariables = ...;

    var publicMethod = function () {};

    that = Object.create({
        publicMethod: publicMethod,
        // public methods and properties
    });
    return that;
};
现在,无论何时你需要一个对象,只要做

var newObject = constructor();

这是更灵活和更清洁的IMHO。如果您忘记键入
new
关键字,它可以避免您意外地污染全局范围。

既然您提到您正在使用Javascript进行OO,那么让我向您介绍一种更干净、更易于阅读和更安全的Javascript对象创建方法。我是在读《Javascript:好的部分》这本好书的时候学会的

下面是创建对象的方法

var constructor = function (spec) {
    var that;

    var privateFunc = function () {};
    var privateVariables = ...;

    var publicMethod = function () {};

    that = Object.create({
        publicMethod: publicMethod,
        // public methods and properties
    });
    return that;
};
现在,无论何时你需要一个对象,只要做

var newObject = constructor();


这是更灵活和更清洁的IMHO。如果您忘记键入
new
关键字,它可以避免意外污染全局范围。

为什么要在“MyChooser构造函数”中定义构造函数与其修改并返回MyChooser实例,我认为您缺少了iife@NicoSantangelo我在一本书中看到过这一点example@Sherman这是什么意思?立即调用函数。return语句后mychooser的结尾应该类似于})(mychooser | | newmychooser());或者类似的。我不记得你是否在extra()中放了这样的东西,但它是这样的,为什么你要在“MyChooser构造函数”中定义构造函数与其修改并返回MyChooser实例,我认为您缺少了iife@NicoSantangelo我在一本书中看到过这一点example@Sherman这是什么意思?立即调用函数。return语句后mychooser的结尾应该类似于})(mychooser | | newmychooser());或者类似的。我不记得你是否把它放进了extra()中,但它是这样的,这都是真的,但是
.prototype
的设置方式也意味着它也不会那样工作。原型任务需要分配给
构造函数。prototype
,而不是
MyChooser.prototype
。非常感谢,现在它可以工作了:))我还将构造函数重命名为MyChooser,以使其更清晰这是真的,但是
prototype
的设置方式也意味着它也不能工作。原型任务需要分配给
constructor.prototype
,而不是
MyChooser.prototype
。非常感谢,现在它可以工作了:))我还将构造函数重命名为MyChooser以使其更清晰谢谢你的constructor->MyChooser提示。让它更清晰谢谢你的构造器->我的选择器提示。更清楚的是,我希望有一个类似Java的类结构,就像我习惯的那样。在构造函数中定义所有内容并不是件好事。。。。但无论如何,我会试试看。你们可能听说过工厂模式。它在Java中被广泛使用。上述构造函数是工厂模式的一个示例。一开始它可能看起来有点奇怪,但它避免了许多不良做法和常见错误。在空闲时间一定要读一读上面提到的书。这是值得的;-)问题是,我希望有一个类似Java的类结构,因为我已经习惯了。在构造函数中定义所有内容并不是件好事。。。。但无论如何,我会试试看。你们可能听说过工厂模式。它在Java中被广泛使用。上述构造函数是工厂模式的一个示例。一开始它可能看起来有点奇怪,但它避免了许多不良做法和常见错误。在空闲时间一定要读一读上面提到的书。这是值得的;-)