为什么我的原型函数中会出现 'this.setData is not a function'?

Why do I get 'this.setData is not a function' in my prototype function?

不久前,我使用 Prototype 创建了一个对话功能。代码如下所示:

//Dialog constructor
var sldialog = function(params, callback){
    this.box         = // (...)
    this.background  = // (...)
    this.buttonPanel = // (...)
    this.callback    = callback;
    this.options     = $.extend({
     // (...)
    },params);

    this.setData();
    this.showDialog();
    this.dialogboxAction();
};

// Dialog functions
sldialog.prototype = {
    setData: function(){ (..) },
    showDialog: function(){ (..) },
    dialogboxAction: function(){ (..) },
};

我使用以下代码调用该函数:

    sldialog({
        title: 'Delete peprson',
        msg: 'Do you really want to delete this person?',
        type: 'action',
        yes: 'Delete person',
        multiDialog: 1
    }, function (confirmed) {
      // (...)
    });

现在我收到错误:this.setData is not a function
我没有太多使用 prototype 的经验,因为我是通过查看一些教程来做到这一点的。

到目前为止,这一直运行良好。我看不出代码中其他地方的变化如何影响这一点。

您的 sldialog 函数是一个 构造函数 函数;您通过 new 调用构造函数。所以你需要把它添加到你调用它的地方:

new sldialog({
    title: 'Delete peprson',
    msg: 'Do you really want to delete this person?',
    type: 'action',
    yes: 'Delete person',
    multiDialog: 1
}, function (confirmed) {
  // (...)
});

原因是,尽管我们称它们为 "constructor functions,",但创建对象的不是函数,而是 new 运算符。 new 创建对象,分配原型,然后调用构造函数 this 引用新对象。


旁注:JavaScript 中的压倒性约定是构造函数名称是初始封顶的。所以也许 SLDialogSldialogSlDialog 而不是 sldialog.


旁注 2:一般来说,我不鼓励人们 替换 函数的 prototype 属性 指向的对象;相反,我建议只添加它:

sldialog.prototype.setData = function() { ... };
sldialog.prototype.showDialog = function() { ... };
sldialog.prototype.dialogboxAction = function() { ... };

(是的,它会重复,所以我通常有一个将属性复制到它的功能。)

喜欢的话可以继续更换;只需确保将 constructor 设置回旧对象的默认值即可:

sldialog.prototype = {
    constructor: sldialog,              // <===
    setData: function(){ (..) },
    showDialog: function(){ (..) },
    dialogboxAction: function(){ (..) },
};

这样,您就可以确保维护原型到构造函数的反向链接。