How can I create a new Person object correctly in Javascript?
I'm still struggling with this concept. I have two different Person objects, very simply:
;Person1 = (function() {
function P (fname, lname) {
P.FirstName = fname;
P.LastName = lname;
return P;
}
P.Firs开发者_高级运维tName = '';
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;
}
})();
And let's say I invoke them like this:
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();
The Person1
set alerts "bill" twice, then alerts "private" once -- so it recognizes the showPrivate
function, but the local FirstName
variable gets overwritten.
The second Person2
set alerts "sal", then "bill", but it fails when the showPrivate
function is called. The new
keyword here works as I'd expect, but showPrivate
(which I thought was a publicly exposed function within the closure) is apparently not public.
How can I ensure that my closure is a reusable object with publicly exposed methods? I am using the (function() { //object code })(); syntax to ensure my variables are scoped only to the object being created. Thanks!
this is using the technique from "JavaScript: The Good Parts" by Douglas Crockford http://oreilly.com/catalog/9780596517748
Chapter 5: Inheritance - section 'Functional'
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
put this together on jsfiddle, link below if you want to test drive it, watch out for the 4 alerts when the page loads
http://jsfiddle.net/SecKg/
I modified Person2 to declare the showPrivate
function within the constructor -- ensuring the function was public:
;Person2 = (function() {
var prName = 'private';
return function(fname, lname) {
this.FirstName = fname;
this.LastName = lname;
this.showPrivate = function() { alert(prName); };
}
})();
You want to be using the prototype method of creating Person objects.
;(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 will be private as it's creating inside the constructor. The getName function is public, and can be invoked from outside the Person object.
I'm not entirely sure what you're trying to accomplish here. Your question is a little confusing. Perhaps try to reword?
//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;
}
};
};
精彩评论