簡體   English   中英

從原型方法訪問構造函數

[英]Access constructor from prototype method

在下面的代碼中,我有一個Mass構造函數和一些方法。 最初,方法在Mass構造函數內部,但是我正在使用許多方法。 因此,為了使事情更有條理,我刪除了Mass之外的一些方法,並使用原型添加了它們。

但是后來我有一個問題。 我不能用this來指Mass ; 它是指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);

小提琴

代碼的舊版本。 一切正常。 我應該為新產品進行哪些更改?

原型並不意味着使構造函數內部的代碼更小。 該原型旨在共享通用功能。 例如,對於所有Mass實例,您的getElement方法都是相同的。 因此,將其放在原型上是理想的。 updateVars相同。

另一方面, this.rotation是對象而不是函數。 Mass每個實例將具有不同的this.rotation屬性。 因此,此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);
    }
});

接下來,我們創建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;
    }
});

最后,我們僅創建一個Mass實例並使其旋轉:

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

親自觀看演示: http : //jsfiddle.net/NL3SJ/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM