[英]Access constructor from prototype method
In the code below, I have a Mass
constructor and some methods. 在下面的代码中,我有一个
Mass
构造函数和一些方法。 Originally, methods were inside the Mass
constructor, but there are many methods I'm using. 最初,方法在
Mass
构造函数内部,但是我正在使用许多方法。 So, to keep things more organized I removed some of the methods outside of the Mass
and add them using prototype. 因此,为了使事情更有条理,我删除了
Mass
之外的一些方法,并使用原型添加了它们。
But then I have an issue. 但是后来我有一个问题。 I can't reference to
Mass
with this
; 我不能用
this
来指Mass
; it refers to window
. 它是指
window
。
function Mass(elm) {
this.getElement = function(element) {
if (typeof element == "string") {
return document.getElementById(element);
}
return element;
};
this.elm = this.getElement(elm);
this.elm.style.position = "absolute";
this.elm.style.left = 0 + "px";
this.elm.style.top = 0 + "px";
this.updateVars = function () {
this.width = parseInt(this.elm.style.width, 10);
this.height = parseInt(this.elm.style.height, 10);
this.top = parseInt(this.elm.style.top, 10);
this.left = parseInt(this.elm.style.left, 10);
this.radius = this.width / 2;
this.originX = this.left + this.radius;
this.originY = this.top + this.radius;
this.worldOrgX = this.originX + parseInt(this.elm.parentNode.style.left, 10);
this.worldOrgY = this.originY + parseInt(this.elm.parentNode.style.top, 10);
};
}
Mass.prototype = {
// other methods here
rotation : {
// this = window
mass : this,
angle : 0,
handler : null,
rotate : function (angularVelocity, rotationSpeed) {
this.angle = (this.angle + angularVelocity) % 360;
// here I need to access Mass.elm and apply rotate
this.mass.elm.style.webkitTransform = "rotate(" + this.angle + "deg)";
},
start : function (angularVelocity, rotationSpeed) {
var rotation = this; // this = Mass.rotation
rotation.handler = setInterval(function () {
rotation.rotate(angularVelocity, rotationSpeed);
}, rotationSpeed);
},
},
}
var earth = new Mass("earth");
//earth.rotation.start(4.5, 25);
Old version of the code. 代码的旧版本。 This is working fine.
一切正常。 What changes should I make for new one to work?
我应该为新产品进行哪些更改?
The prototype is not meant to make the code inside your constructor smaller. 原型并不意味着使构造函数内部的代码更小。 The prototype is meant to share common functionality.
该原型旨在共享通用功能。 For example your
getElement
method is the same for all instances of Mass
. 例如,对于所有
Mass
实例,您的getElement
方法都是相同的。 Hence it would be ideal to put it on the prototype. 因此,将其放在原型上是理想的。 Same for
updateVars
. 与
updateVars
相同。
On the other hand this.rotation
is an object and not a function. 另一方面,
this.rotation
是对象而不是函数。 Every instance of Mass
will have a different this.rotation
property. Mass
每个实例将具有不同的this.rotation
属性。 Hence this.rotation
cannot be shared and hence must not be put on the prototype. 因此,此
this.rotation
不能共享,因此不能放在原型上。
I usually like to create "classes" in JavaScript using a simple defclass
function: 我通常喜欢使用简单的
defclass
函数在JavaScript中创建“类”:
function defclass(prototype) {
var constructor = prototype.constructor;
constructor.prototype = prototype;
return constructor;
}
The defclass
function unwraps a prototype and returns its constructor. defclass
函数解包原型并返回其构造函数。 By the way, the constructor is just another method on the prototype. 顺便说一下,构造函数只是原型上的另一种方法。
So here's how I would rewrite your Mass
class: 因此,这就是我重写您的
Mass
类的方法:
var Mass = defclass({
constructor: function (id) {
var element = this.element = this.getElement(id);
var style = element.style;
style.position = "absolute";
style.left = 0;
style.top = 0;
this.rotation = new Rotation(this);
},
getElement: function (id) {
if (typeof id !== "string") return id;
else return document.getElementById(id);
}
});
Next we create the Rotation
class: 接下来,我们创建
Rotation
类:
var Rotation = defclass({
constructor: function (mass) {
this.mass = mass;
this.angle = 0;
},
start: function (angularVelocity, delay) {
var rotation = this;
setInterval(function () {
rotation.rotate(angularVelocity);
}, delay);
},
rotate: function (angularVelocity) {
var angle = this.angle = (this.angle + angularVelocity) % 360;
var transform = "rotate(" + angle + "deg)";
var style = this.mass.element.style;
style.webkitTransform = transform;
style.mozTransform = transform;
style.msTransform = transform;
style.oTransform = transform;
style.transform = transform;
}
});
Finally we simply create an instance of Mass
and make it rotate: 最后,我们仅创建一个
Mass
实例并使其旋转:
var earth = new Mass("earth");
earth.rotation.start(4.5, 25);
See the demo for yourself: http://jsfiddle.net/NL3SJ/ 亲自观看演示: http : //jsfiddle.net/NL3SJ/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.