我试图在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调用,但这不是问题)
答案 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
关键字,它可以避免意外污染全局范围。