我正在学习使用prototype属性在JavaScript上定义'class like'函数。
当我像这样定义一个People
类时,一切都很好:
var People = function(firstName, lastName){
// public
this.firstName = firstName;
this.lastName = lastName;
this.fullName = function(){
console.log(full_name);
return this;
};
// private
var self = this;
var full_name = function(){
return self.firstName + ' ' + self.lastName;
}();
};
var person = new People('John', 'Smith');
person.fullName(); // => "John Smith"
但是,当我将fullName
方法移动到初始定义之外时,如下所示:
var People = function(firstName, lastName){
// public
this.firstName = firstName;
this.lastName = lastName;
// private
var self = this;
var full_name = function(){
return self.firstName + ' ' + self.lastName;
}();
};
People.prototype.fullName = function(){
console.log(full_name);
return this;
};
var person = new People('John', 'Smith');
person.fullName(); // => "ReferenceError: full_name is not defined"
我收到了一个错误。我不明白为什么...... ??
答案 0 :(得分:3)
下面:
var full_name = function(){
return self.firstName + ' ' + self.lastName;
}();
您将变量“full_name”设置为调用该匿名函数的结果。它只是在该构造函数的上下文中声明的变量,但是,这并不重要;构造函数之外的任何东西都无法访问它。
因此,在该原型函数中,您会收到错误,因为“full_name”实际上是而不是定义的。如果你想在原型上使用全名函数,只需在那里声明:
People.prototype.fullName = function() {
return this.firstName + " " + this.lastName;
};
如果你想要一个只能在构造函数中访问代码的“私有”函数,那么你可以这样做:
var People = function(firstName, lastName){
// public
this.firstName = firstName;
this.lastName = lastName;
// private
var self = this;
function fullName(){
return self.firstName + ' ' + self.lastName;
}
this.addressMe = function(msg) {
return fullName() + ": " + msg;
};
};
然后你可以这样做:
var bob = new People("Bob", "Scum");
alert( bob.addressMe("stand and deliver") ); // "Bob Scum: stand and deliver"
答案 1 :(得分:1)
Pointy对私有共享成员使用了错误的模式,该模式适用于私有特定于实例的成员,并且每个实例都拥有自己的addressMe函数。
私有共享成员的模式可以将原型包装在IIFE中:
var People = function(firstName, lastName){
// public
this.firstName = firstName;
this.lastName = lastName;
};
(function(){
// private shared member
var full_name = function(){
return this.firstName + ' ' + this.lastName;
};
//privileged member that has access to private shared
// fullName is a closure and full_name is available
// in the colosure scope created for this function
People.prototype.fullName = function(){
//calling private member, make sure you set
// the invoking object (this) by using
// Function.prototype.call
console.log(full_name.call(this));
return this;
};
}());
var person = new People('John', 'Smith');
person.fullName();
您不能将此模式用于特定的私有成员,但函数full_name不是特定于实例的。
可以找到受保护的模式以及有关原型和构造函数的更多信息here。