JavaScript范围问题(this)

时间:2015-06-12 21:57:50

标签: javascript

我试图以面向对象的方式组织我的代码(如MDN中所述)。但是在我的情况下, this 指的是窗口对象。因此我得到了错误

  

未捕获的TypeError:无法读取未定义的属性'render'

  

this.renderer.render(this.stage);

为什么当它不在MDN上时会引用窗口对象?

var GAME = GAME || {};

GAME.Application = function() {
    this.renderer = PIXI.autoDetectRenderer(800, 600,{backgroundColor : 0x1099bb});
    document.getElementById("game").appendChild(this.renderer.view);
    this.stage = new PIXI.Container();
    requestAnimationFrame(this.render);
}

GAME.Application.prototype.render = function() {
    this.renderer.render(this.stage);
}

var app = new GAME.Application();

2 个答案:

答案 0 :(得分:4)

您需要绑定render功能。这可能是最直接的解决方案。

requestAnimationFrame(this.render.bind(this));

或者你可以做

var context = this;
requestAnimationFrame(function() {
  context.render();
});

或者您可以避免创建自由变量并使用IIFE

requestAnimationFrame((function(context) {
  context.render();
})(this)));

或者,如果您正在使用ES6,则可以使用箭头功能

requestAnimationFrame(() => this.render());

您可以做的另一项简单改进是将render元素传递给Application构造函数

function Application(elem) {
  this.renderer = ...
  elem.appendChild(this.renderer.view);
}

new Application(document.getElementById("game"));

答案 1 :(得分:1)

让我们谈谈this,背景和功能

考虑它的好方法是,this引用调用它的方法的.左侧的对象。

var someObj = {
    name:'someObj',
    sayName: function(){
        console.log(this.name);
    }
};

someObj.sayName(); // prints someObj

不是对象方法的函数绑定到窗口对象。

window.name = 'window';
function sayName(){
    console.log(this.name);
}

sayName(); //prints window

以上相当于

window.sayName(); // window is on the left of the dot, so it is `this`

当您将对象的方法作为参数传递或将其分配给变量时,它会丢失其原始上下文。下面,someObj的sayName方法失去someObj作为上下文并获得someOtherObj。

var someOtherObj = {
    name:'someOtherObj'
};

someOtherObj.sayName = someObj.sayName;

someOtherObj.sayName(); // prints someOtherObj

要解决此问题,您可以将上下文绑定到函数

var yetAnotherObj = {
    name: 'yetAnotherObj'
};

var sayYetAnotherObj = sayName.bind(yetAnotherObj);

sayYetAnotherObj(); // prints yetAnotherObj

或者传递一个匿名函数,该函数调用对象本身的方法

var OneLastObj = function(){
    var self = this;
    this.someValue = aFunctionTakingAcallback(function(){
        return self.doSomeStuff();
    });
}

将函数作为参数传递时需要记住的是要传递对函数的引用。函数本身并不绑定到它可能是方法的对象。