Javascript Class - undefined 在调用函数时不是函数

Javascript Class - undefined is not a function when calling function

我正在尝试在 javascript 中编写 OO 程序。执行此操作有多种变体。

我在一些 AnglularJS 示例中看到了一些我认为对我来说最清晰的示例。

遗憾的是我得到了

undefined is not a function

调用我的实例的函数时

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 ()

没有它,您的 constructor 就不会 assigned/returned 到 MyChooser。你最终得到 MyChooser 是 returns 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 而不是构造函数,以及构造函数是如何定义的。

既然你提到你在 Javascript 中进行 OO,让我向你介绍一种在 javascript 中创建对象的更好方法,它更清晰、更易于阅读,并且 更安全。我是在看好书的时候学的"Javascript: The Good Parts"

以下是创建对象的方法。

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();

恕我直言,这更加灵活和简洁。如果您忘记输入 new 关键字,它可以避免意外污染全局范围。