local variable not accessed & 'this' context enforcement
i have the following piece of code that is giving me trouble working [question(s) after code]
var LIB = function(){};
(function(){
var JSExpert = function(lname){
if(!(this instanceof arguments.callee)){
return new JSExpert(lname);
}
this.fname = "Later ";
this.name = this.fname + lname;
};
JSExpert.prototype = {
setFname: function(fname){
开发者_开发知识库 this.fname = fname;
return this; //for chaining
},
getName: function(){
alert("javascript expert name is " + this.name);
}
};
LIB.Expert = JSExpert;
return;
window.JSExpert = JSExpert;
})();
Now here come the test code
LIB.Expert("Edwads").setFname("Dean").getName();
Now when you try the code the setFname() method which is supposed to change "Later " in the constructor by "Dean" isn't doing it, why is that????
Second question: we're using 'this' inside JSExpert. how can one be sure the context of 'this' isn't bound later to the context of 'LIB' and stay enforced to that of 'JSExpert' and thus 'LIB.Expert' ?
Thanks
1) Change
setFname: function(fname){
this.fname = fname;
return this; //for chaining
},
to
setFname: function(fname){
this.name = this.name.slice(this.fname.length);
this.name = fname + ' ' + this.name;
this.fname = fname + ' ';
return this; //for chaining
},
2) In the contructor function you check this
type:
var JSExpert = function(lname){
//If not an instance of this class creates a new object of this class and return it
if(!(this instanceof arguments.callee)){
return new JSExpert(lname);
}
this.fname = "Later ";
this.name = this.fname + lname;
};
In the other functions you can do something like if (!(this instanceof JSExpert)) throw new Error('');
, throwing an error is the best you can do here, this is a drawnback in using the prototype.
Because this:
return;
window.JSExpert = JSExpert;
is not correct, should be:
window.JSExpert = JSExpert;
and
getName: function(){
alert("javascript expert name is " + this.name);
}
should be:
getName: function(){
alert("javascript expert name is " + this.fname + this.lname);
}
and lname
needs to be a property like fname. Example
var LIB = function() {};
(function() {
var JSExpert = function(lname) {
if (!(this instanceof arguments.callee)) {
return new JSExpert(lname);
}
this.lname = lname;
this.fname = "Later ";
this.name = this.fname + lname;
};
JSExpert.prototype = {
setFname: function(fname) {
this.fname = fname;
return this; //for chaining
},
getName: function() {
alert("javascript expert name is " + this.fname + ' ' + this.name);
}
};
LIB.Expert = JSExpert;
//window.JSExpert = JSExpert;
})();
LIB.Expert("Edwads").setFname("Dean").getName();
精彩评论