【问题标题】:Object Oriented Javascript Prototype, Access Root Variables?面向对象的 Javascript 原型,访问根变量?
【发布时间】:2012-12-04 07:05:28
【问题描述】:

让我们开始吧。 我在 Javascript 中创建了一个有效的“惯性相机”,虽然我在 Javascript 方面非常有经验,但我没有在 JS 中进行原型设计的经验。我正在尝试使用初始函数构造函数如下重构我的相机:

    function Inertia(subject, clickable) {
        this.subject = document.getElementById(subject);
        this.clickable = document.getElementById(clickable);
    }

还有原型:

    Inertia.prototype = {
        subject : document.getElementById(''),
        clickable : document.getElementById(''),
        camera : { angleX : 85, angleY : 0, angleZ : 0, translateX : 0, translateY : -100, depth : 0, flag : 1 },
        mouse  : { x : 0, y : 0 },
        friction : 1,
        inertia : true,

        mouseEvents : {
            mouseDown   :   function( e ) {
                                var IS = this; // This will not work because I am two levels away from "this" being my object.

                                // cancel existing animation
                                clearTimeout((window).animation);

                                (IS).mouse.x = e.clientX;
                                (IS).mouse.y = e.clientY;
                                (IS).camera.flag = 0;

                                // begin logging history to animate from as a new history stack
                                (IS).tools.pushHistory('reset');
                            },

... 继续 ...

我的问题是在我的原型对象中,我无法访问根级元素,例如 mouse.xmouse.y。在创建这样的原型时,为我的“惯性”类的这个特定实例访问这些元素的最佳方法是什么?这是完全错误的想法吗?

我希望以这种方式了解原型的正确实现。我查看了有关原型设计的教程和文章,但我还没有看到任何解决此嵌套问题的示例。他们都在原型中使用了一层,因此调用this 没有问题。

我试图让var IS 等于当前对象,因此在这个惯性相机的每个实例中,我只会改变那个特定的对象。但是,我的原型有两个层次,所以this 关键字不起作用。如果我只有一个new Inertia() 的实例,我可以将它硬编码为变量名,但这显然是不可取的。

【问题讨论】:

    标签: javascript class object constructor prototype


    【解决方案1】:

    属性通常位于原型的构造函数和方法中。我认为您可能遗漏了一些概念;在原型中创建(和复制)属性没有意义,因为属性对于实例是唯一的。如果这些变量是私有的,通常的约定是在它前面加上一个下划线:

    function Inertia( subject, clickable ) {
    
      this.subject = document.getElementById( subject );
      this.clickable = document.getElementById( clickable );
    
      // Private vars unique to each instance
      this._camera = { ... };
      this._mouse = { ... };
      this._friction = 1;
      this._inertia = true;
    
    }
    
    Inertia.prototype = {
    
      mouseDown: function( e ) {
        var self = this;
        // Now you can access and modify the private vars:
        self._mouse.x = e.clientX;
        ...
      }
    
    };
    

    【讨论】:

    • 我绝对同意第一部分,我会改变它。关于原型:我将我的函数组合在嵌套对象中以增加一些可读性等。您删除了“mouseEvents”,这是我实现中的真正障碍。我想我的部分问题是,我是否应该使用我正在使用的嵌套结构?甚至可能吗?我正在尝试尽可能“标准化”。正如@Asad 指出的那样,我已经习惯于开发纯粹的功能,并且正在尝试一些新的东西,因为我似乎看到了大量使用嵌套对象格式的插件。
    • 你可以在原型中嵌套对象,是的,但我不会那样做,我会像你已经拥有的那样在它前面加上前缀,如果它是一个鼠标事件,那么在它前面加上 mouse , 如果是键盘事件,则在其前面加上 kbd 等...
    最近更新 更多