如何在Javascript中正确创建新的Person对象?

时间:2010-05-26 22:38:41

标签: javascript closures

我仍在努力解决这个问题。我有两个不同的Person对象,非常简单:

;Person1 = (function() {
    function P (fname, lname) {
        P.FirstName = fname;
        P.LastName = lname;
        return P;
    }
    P.FirstName = '';
    P.LastName = '';
    var prName = 'private';
    P.showPrivate = function() { alert(prName); };
    return P;
})();

;Person2 = (function() {
    var prName = 'private';
    this.FirstName = '';
    this.LastName = ''; 
    this.showPrivate = function() { alert(prName); };
    return function(fname, lname) {
        this.FirstName = fname;
        this.LastName = lname;
    }   
})();

让我们说我像这样调用它们:

var s = new Array();

//Person1
s.push(new Person1("sal", "smith"));
s.push(new Person1("bill", "wonk"));
alert(s[0].FirstName);
alert(s[1].FirstName);
s[1].showPrivate();

//Person2
s.push(new Person2("sal", "smith"));
s.push(new Person2("bill", "wonk"));
alert(s[2].FirstName);
alert(s[3].FirstName);
s[3].showPrivate();

Person1设置警报“帐单”两次,然后警告“私有”一次 - 因此它识别showPrivate函数,但本地FirstName变量被覆盖。

第二个Person2设置警告“sal”,然后“bill”,但在调用showPrivate函数时失败。这里new关键字的效果与我预期的一样,但showPrivate(我认为它是封闭内部公开的函数)显然不公开。

如何确保我的闭包是一个具有公开暴露方法的可重用对象?我正在使用(function(){// object code})();语法,以确保我的变量仅限于正在创建的对象。谢谢!

4 个答案:

答案 0 :(得分:3)

这是使用Douglas Crockford的“JavaScript:The Good Parts”中的技术 http://oreilly.com/catalog/9780596517748

第5章:继承 - “功能”部分

var personConstructor = function (spec) {
    var that = {};

    that.fullName = function () {
            return spec.first_name + " " + spec.last_name;
    };

    that.setFirstName = function (firstName) {
            spec.first_name = firstName;
    };

    return that;
};

var john = personConstructor({first_name: "John", last_name: "Doe"});
var jane = personConstructor({first_name: "Jane", last_name: "Doe"}); 

alert(john.fullName()); // John Doe
alert(jane.fullName()); // Jane Doe

john.first_name = "OVERWRITE";
alert(john.fullName()); // John Doe

john.setFirstName("OVERWRITE-VIA-SETTER");
alert(john.fullName()); // OVERWRITE-VIA-SETTER Doe

将它放在jsfiddle上,如果你想试驾它,请在下面链接, 在页面加载时注意4个警报

http://jsfiddle.net/SecKg/

答案 1 :(得分:0)

您希望使用创建Person对象的原型方法。

;(function(){
    function Person(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;

        function showPrivate() {
            alert(this.firstName);
        }
    }

    Person.prototype.getName = function() {
        return this.firstName + ' ' + this.lastName;
    }

})();    

showPrivate将是私有的,因为它在构造函数中创建。 getName函数是public,可以从Person对象外部调用。

我不完全确定你在这里想要完成什么。你的问题有点令人困惑。也许试着改写?

答案 2 :(得分:0)

我修改了Person2以在构造函数中声明showPrivate函数 - 确保函数是公共的:

;Person2 = (function() {
    var prName = 'private';
    return function(fname, lname) {
        this.FirstName = fname;
        this.LastName = lname;
        this.showPrivate = function() { alert(prName); };
    }
})();

答案 3 :(得分:0)

//this would allow for instance:
//  john.setName('first', 'Johnny');
//  jane.setName('last', 'Smith');
var personConstructor = function (spec) {
    return {
        fullName: function () {
            return spec.first_name + " " + spec.last_name;
        },
        setName: function (nameType, name) {
            spec[nameType+'_name'] = name;
        }
    };
};