Javascript 从原型方法访问构造函数

Javascript 从原型方法访问构造函数,javascript,constructor,scope,prototype,Javascript,Constructor,Scope,Prototype,在下面的代码中,我有一个Mass构造函数和一些方法。最初,方法在Mass构造函数中,但我正在使用许多方法。所以,为了使事情更有条理,我删除了Mass之外的一些方法,并使用prototype添加它们 但我有个问题。我不能用这个引用质量;它指的是窗口 function Mass(elm) { this.getElement = function(element) { if (typeof element == "string") { r

在下面的代码中,我有一个
Mass
构造函数和一些方法。最初,方法在
Mass
构造函数中,但我正在使用许多方法。所以,为了使事情更有条理,我删除了
Mass
之外的一些方法,并使用prototype添加它们

但我有个问题。我不能用
这个
引用
质量
;它指的是
窗口

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);


这很好用。我应该做哪些更改才能使新的工作?

原型并不意味着要使构造函数中的代码变小。原型旨在共享通用功能。例如,您的
getElement
方法对于
Mass
的所有实例都是相同的。因此,将其放在原型上是理想的。同样适用于
updateVars

另一方面,旋转是一个对象,而不是一个函数。
Mass
的每个实例将具有不同的
this.rotation
属性。因此,
这个旋转不能共享,因此不能放在原型上

我通常喜欢使用简单的
defclass
函数在JavaScript中创建“类”:

function defclass(prototype) {
    var constructor = prototype.constructor;
    constructor.prototype = prototype;
    return constructor;
}
defclass
函数打开原型并返回其构造函数。顺便说一下,构造函数只是原型上的另一种方法

下面是我如何重写你的
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);
    }
});
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;
    }
});
接下来,我们创建
Rotation
类:

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);
    }
});
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;
    }
});
最后,我们只需创建一个
Mass
实例并使其旋转:

var earth = new Mass("earth");
earth.rotation.start(4.5, 25);

亲自查看演示:

看看以下内容是否有用:
如果您当时还没有创建实例,您怎么会认为
将引用
Mass
的实例
这个
不是很复杂,看看@PM稍微不同的问题,Mass有一个旋转,op需要知道旋转中的Mass实例。旋转中的该值将正确地为旋转(调用对象),但op不知道如何从那里到达体量实例。您可以为每个体量实例指定一个旋转实例,并在那里引用体量实例。关于构造函数、原型和它的值的更多信息可以在这里找到。尽管我没有完全使用你建议的方法,但它帮助我解决了这个问题。它澄清了一些事情。这个学期让我有点害怕。我以前在C#中创建过一些应用程序,但我对类还是不太熟悉。无论如何,我现在可以访问
Mass
,代码看起来更有条理。非常感谢。