Tau*_*ren 23 javascript oop prototype
通常,我已经看到在类定义之外声明的原型函数,如下所示:
function Container(param) {
this.member = param;
}
Container.prototype.stamp = function (string) {
return this.member + string;
}
var container1 = new Container('A');
alert(container1.member);
alert(container1.stamp('X'));
Run Code Online (Sandbox Code Playgroud)
此代码生成两个值为"A"和"AX"的警报.
我想定义类定义的原型函数INSIDE.做这样的事情有什么不对吗?
function Container(param) {
this.member = param;
if (!Container.prototype.stamp) {
Container.prototype.stamp = function() {
return this.member + string;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试这样,以便我可以访问类中的私有变量.但是我发现如果我的原型函数引用了私有var,那么private var的值总是初始化函数初始化时使用的值,而不是对象实例中的值:
Container = function(param) {
this.member = param;
var privateVar = param;
if (!Container.prototype.stamp) {
Container.prototype.stamp = function(string) {
return privateVar + this.member + string;
}
}
}
var container1 = new Container('A');
var container2 = new Container('B');
alert(container1.stamp('X'));
alert(container2.stamp('X'));
Run Code Online (Sandbox Code Playgroud)
此代码生成两个值为"AAX"和"ABX"的警报.我希望输出为"AAX"和"BBX".我很好奇为什么这不起作用,如果有其他模式我可以使用.
编辑:请注意,我完全理解,对于这个简单的例子,最好只使用一个闭包,this.stamp = function() {}
而不是使用原型.我就是这样做的.但我正在尝试使用原型来了解更多相关内容,并希望了解一些事情:
Date
.我读过闭包更快.CMS*_*CMS 22
何时使用原型函数而不是闭包是有意义的?
嗯,这是最轻量级的方法,假设你在prototype
某个构造函数中有一个方法,并且你创建了1000个对象实例,所有这些对象都将在你的原型链中拥有你的方法,而且所有这些对象都只引用一个功能对象.
如果在构造函数中初始化该方法,例如(this.method = function () {};
),则所有1000个对象实例都将具有一个函数对象作为自己的属性.
如果我出于某种原因需要使用原型函数,那么在类中定义它是否"OK",就像在我的例子中一样,或者它应该在外面定义?
在其自身内部定义构造函数原型的成员并没有多大意义,我将向您解释更多关于它的原因以及为什么您的代码不起作用.
我想了解为什么原型函数无法访问每个实例的privateVar值,只有第一个实例的值.
我们来看看你的代码:
var Container = function(param) {
this.member = param;
var privateVar = param;
if (!Container.prototype.stamp) { // <-- executed on the first call only
Container.prototype.stamp = function(string) {
return privateVar + this.member + string;
}
}
}
Run Code Online (Sandbox Code Playgroud)
关于代码行为的关键点是该Container.prototype.stamp
函数是在第一个方法调用时创建的.
在创建函数对象时,它会将当前封闭范围存储在名为的内部属性中[[Scope]]
.
当您通过使用var
函数或FunctionDeclaration 在其中声明的标识符(变量)调用函数时,稍后会扩充此作用域.
[[Scope]]
属性列表构成了作用域链,当您访问标识符(如privateVar
变量)时,将检查这些对象.
并且由于您的函数是在第一个方法调用(new Container('A')
)上创建的,privateVar
因此绑定到第一个函数调用的Scope,无论您如何调用该方法,它都将保持绑定.
看看这个答案,第一部分是关于with
声明,但在第二部分我讨论范围链如何为函数工作.
Mat*_*att 12
很抱歉复活了一个旧问题,但我想在SO上添加我最近在其他地方发现的东西(寻找链接,一旦找到它就会编辑/添加它):找到它.
我个人喜欢以下方法,因为我可以直观地将我的原型和'实例'定义与函数定义一起分组,同时避免多次评估它们.它还提供了使用原型方法进行闭包的机会,这对于创建由不同原型方法共享的"私有"变量非常有用.
var MyObject = (function () {
// Note that this variable can be closured with the 'instance' and prototype methods below
var outerScope = function(){};
// This function will ultimately be the "constructor" for your object
function MyObject() {
var privateVariable = 1; // both of these private vars are really closures specific to each instance
var privateFunction = function(){};
this.PublicProtectedFunction = function(){ };
}
// "Static" like properties/functions, not specific to each instance but not a prototype either
MyObject.Count = 0;
// Prototype declarations
MyObject.prototype.someFunction = function () { };
MyObject.prototype.someValue = 1;
return MyObject;
})();
// note we do automatic evalution of this function, which means the 'instance' and prototype definitions
// will only be evaluated/defined once. Now, everytime we do the following, we get a new instance
// as defined by the 'function MyObject' definition inside
var test = new MyObject();
Run Code Online (Sandbox Code Playgroud)