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

时间:2015-03-08 15:50:09

标签: javascript class oop iife

我试图在javascript中编写OO。这样做有几种变体。

我在一些AnglularJS例子中看到了一些对我来说最清楚的例子。

可悲的是我得到了

  

undefined不是函数

调用我的实例的函数时

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调用,但这不是问题)

3 个答案:

答案 0 :(得分:3)

你最后没有()来使封闭功能成为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将无法分配/返回MyChooser。您最终将MyChooser作为返回constructor的函数,而不是constructor本身。另外,将原型方法更改为指向constructor而不是MyChooser

此外,所有这些混淆都源于构造函数及其方法定义放在闭包中这一事实 - 这是不必要的。您可以简单地使用:

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

...

var fp = new MyChooser(...);

答案 1 :(得分:1)

这可行:

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

    }

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

    return MyChooser 
})();

var thisChooser = new MyChooser(param1, param2);

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

答案 2 :(得分:0)

由于你提到你在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关键字,它可以避免意外污染全局范围。