有没有更惯用的写作方式?

时间:2014-08-28 05:33:55

标签: javascript constructor prototype

我有点担心这个问题不是正确的形式,所以如果有更好的方式来表达/提出这个问题,请告诉我。

基本上,我前几天正在阅读有人制作的坐标系。这很酷,我想到将如何让自己变得更好。所以我做到了。

简而言之,它将墨卡托地图划分为36个区域,递归地,每个区域用数字或字母表示(帽子不重要)。

无论如何,我用一类叫做Zone的Javascript对象代表它。但是,构造函数使用了一些对象的原型方法。不知道还能做什么,我这样做了(你可以忽略它的主要内容,我主要是查询对象结构):

// Internally, zones are represented from (0,0) to (1,1), as in the positive quadrant
// on the Cartesian plane. Since it is just a square, we only need the bottomLeft
// point and a 'zoomLevel' to determine the side lengths, which is (1/6)**zoomLevel.
var Zone = function () { this.constructor.apply(this,arguments) }
Zone.prototype = {
    constructor: function(address) {
        if (!address) {
            this.x = 0
            this.y = 0
            this.address = ""
            this.zoomLevel = 0
        } else {
            this.address = address.toString(36)
            coords = hexcoords(this.address.slice(0,1))
            this.x = coords[0]
            this.y = coords[1]
            this.zoomLevel = 1
        }
        while (this.zoomLevel < this.address.length) {
            this.descend(this.address.slice(this.zoomLevel, this.zoomLevel+1), true)
        }
    },
    topRight: function () { return [ this.x + Math.pow((1/6),this.zoomLevel),
                                     this.y + Math.pow((1/6),this.zoomLevel) ] },
    toLatLong: function (x,y) {
        // top left corner is -180 longitude and 85.05112878
        if (!x && !y) {
            // latitude and longitude are kind of reversed from x/y
            return [85.05112878 - 170.1022*(1-this.y), -180 + 360 * this.x ]
        }
        return [85.05112878 - 170.1022*(1-y), -180 + 360 * x ]
    },
    clone: function () { return new Zone(this.address) },
    // Descending is basically just always moving the bottomLeft point some nonnegative
    // amount in the positive direction. Luckily, the subzone allows us to calculate
    // that easily.
    descend: function (zone, dontchangeaddress) {
        this.x += Math.pow((1/6),this.zoomLevel)*hexcoords(zone)[0]
        this.y += Math.pow((1/6),this.zoomLevel)*hexcoords(zone)[1]
        if (!dontchangeaddress) {
            this.address = this.address.concat(zone.toString(36))
        }
        this.zoomLevel += 1
        return this
    }
}

基本上,我的问题是询问是否有更好或更惯用的方法来定义一个Object及其属性,以便它们可以在构造函数中使用?

(如果需要,请随意提出其他形式的批评或建议。)

1 个答案:

答案 0 :(得分:0)

你可以安全地写

Zone = function(address) {
    if (!address) {
        this.x = 0
        this.y = 0
        this.address = ""
        this.zoomLevel = 0
    } else {
        this.address = address.toString(36)
        coords = hexcoords(this.address.slice(0,1))
        this.x = coords[0]
        this.y = coords[1]
        this.zoomLevel = 1
    }
    while (this.zoomLevel < this.address.length) {
        this.descend(this.address.slice(this.zoomLevel, this.zoomLevel+1), true)
    }
};

如果你在扩充原型之前没有实际调用 Zone

Zone.prototype = ...
new Zone(); // ok

或者,更一般化:
在Javascript中,任何函数都可以引用在定义函数时似乎不存在的对象属性。这是因为在实际调用函数之前,即在运行时,才会解析引用。