Javascript类方法返回'未定义'

Javascript class methods returning 'undefined'

本文关键字:未定义 类方法 返回 Javascript      更新时间:2023-09-26

这个问题可能有一个快速的答案,但是,我不知道我做错了什么。我有一个类电子邮件列表:

var EmailList = function(id, name, expire_date)
{
    var instance = this;
    var list_id = id;
    var list_name = name;
    var expire_date = expire_date;
    var is_editing = false;
    this.get_list_id = function() { return instance.list_id; }
    this.get_list_name = function() { return instance.list_name; }
    this.get_expire_date = function() { return instance.expire_date; }
    this.is_editing = function() { return instance.is_editing; }
}

我很困惑,因为当我调用类上的任何方法时,比如:

console.log(list.get_list_name());
console.log(list.get_list_id());

因此,我得到了"未定义"。这是怎么回事?

您没有初始化实例数据。与其声明本地变量来存储参数,不如尝试以下操作:

var EmailList = function(id, name, expire_date)
{
    var instance = this;
    instance.list_id = id;
    instance.list_name = name;
    instance.expire_date = expire_date;
    instance.is_editing = false;
    this.get_list_id = function() { return instance.list_id; }
    this.get_list_name = function() { return instance.list_name; }
    this.get_expire_date = function() { return instance.expire_date; }
    this.is_editing = function() { return instance.is_editing; }
}

顺便说一句,更好的方法是消除instance变量,将实例方法更改为使用this,并使用原型定义方法:

var EmailList = function(id, name, expire_date)
{
    this.list_id = id;
    this.list_name = name;
    this.expire_date = expire_date;
    this.is_editing = false;
};
EmailList.prototype = {
    get_list_id : function() { return this.list_id; },
    get_list_name : function() { return this.list_name; },
    get_expire_date : function() { return this.expire_date; },
    is_editing : function() { return this.is_editing; }
};

这样就不会为EmailList的每个实例创建单独的成员函数对象。

Ted Hopp答案中的两个例子都会让你的代码正常工作,但看起来你可能正在尝试为私有字段(或与私有字段等效的JavaScript)创建访问器。如果是这样,你最好这样做:

var EmailList = function(id, name, expire_date)
{
    var list_id = id;
    var list_name = name;
    // Clone input date so it can't be modified externally
    var expire_date = cloneDate(expireDate);
    var is_editing = false;
    this.get_list_id = function() { return list_id; }
    this.get_list_name = function() { return list_name; }
    // Clone date so it can't be modified externally
    this.get_expire_date = function() { return cloneDate(expire_date); }
    this.is_editing = function() { return is_editing; }
    function cloneDate(date) {
        return date && date.getTime && new Date(date.getTime());
    }
}

或者您可以这样做,并跳过三个额外的变量声明:

var EmailList = function(id, name, expire_date)
{
    var is_editing = false;
    // Clone input date so it can't get modified externally
    expire_date = cloneDate(expire_date);
    this.get_list_id = function() { return id; }
    this.get_list_name = function() { return name; }
    // Clone date so it can't get modified externally
    this.get_expire_date = function() { return cloneDate(expire_date); }
    this.is_editing = function() { return is_editing; }
    function cloneDate(date) {
        return date && date.getTime && new Date(date.getTime());
    }
}

这将确保不能从对象外部修改list_idlist_nameexpire_dateis_editing

EcmaScript 5中提供的另一种选择是创建真正的只读属性,任何人都不能修改:

var EmailList = function(id, name, expire_date) {
    Object.defineProperties(this, {
        list_id: { value: id, writable: false },
        list_name: { value: name, writable: false },
        expire_date: { value: cloneDate(expire_date), writable: false },
        is_editing: { value: false, writable: false });
    function cloneDate(date) {
        return date && date.getTime && new Date(date.getTime());
    }
}

我认识到,将is_editing完全只读可能没有意义,但希望这能给你一些好主意。