我是原型的新手,我只是做了一个不起作用的简单例子。从下面的代码可以看出我想要的东西 - 一个柜台。但由于某种原因,输出总是5
,我想bind
正在制作this
对象的深层副本,然后绑定到该函数。有一个明显的解决方案,我公开一切,但我想知道是否有一个更优雅的解决方案。 (或者你可以纠正我的并告诉我没有深拷贝,但是其他一些错误)。 documentation没有帮助我。
代码:
<!DOCTYPE html>
<html>
<body>
<input type="button" value="click" onclick="javascript: doTest();" />
<div id="canvas"></div>
<script>
var ClassA = function (position, element) { // constructor
this.field1 = position;
this.target = element;
};
ClassA.prototype = function () {
// private functions
var _aPrivateMethod = function(){
console.log(this);
this.field1 += 1;
return this.field1;
};
var _aPublicMethod = function(){
this.target.innerHTML = _aPrivateMethod.bind(this)();
};
return { // interface
constructor: ClassA,
aPublicMethod : _aPublicMethod
};
}();
function doTest() {
var obj = new ClassA(4, document.getElementById('canvas'));
obj.aPublicMethod();
}
</script>
</body>
</html>
答案 0 :(得分:1)
以下是一些问题。首先,您每次都致电doTest
。每次点击都会创建一个新对象,因此无法增加field1
。
据我了解,您希望field1
是私密的。在初始化它的方式中,它不能是私有的。你可以这样做:
function Person() {
var counter = 0;
this.increment = function () {
return ++counter;
}
}
这样您就无法从功能范围之外访问counter
。
另一个问题是您没有使用正确的上下文调用私有方法。你应该像pimvdb提到的那样使用_aPrivateMethod.call(this)
。
以下是一个例子:
function Person() {
var age = 0;
function incrementAge() {
return ++age;
}
function eatCake() {
console.log('Yey. I\'ll eat cake!');
}
this.birthday = function () {
eatCake();
return incrementAge();
}
}
var p = new Person();
p.birthday(); //'Yey. I'll eat cake!', returns 1
p.birthday(); //'Yey. I'll eat cake!', returns 2
由于功能范围,eatCake
,incrementAge
和age
都是私有的。
示例中的坏处是我声明函数birthday
的方式。对于Person
的每个实例,将创建一个新副本。
正确的方法是:
Person.prototype.birthday = function () { ... }
我的声明与此不同,因为我想使用私人数据成员。实际上,该功能不仅仅是本地的age
,eatCake
,incrementAge
)。
没有办法从原型中声明的函数访问它们,所以这就是为什么上面的例子我选择了这种方法。