JavaScript范围问题(此)

JavaScript范围问题(此),javascript,Javascript,我尝试以面向对象的方式组织代码(如中所述)。然而,在我的例子中,这是指窗口对象。因此我得到了错误 未捕获的TypeError:无法读取未定义的属性“render” 在 this.renderer.render(this.stage) 为什么这指的是窗口对象,而它不在MDN上 var GAME = GAME || {}; GAME.Application = function() { this.renderer = PIXI.autoDetectRenderer(800, 600,{ba

我尝试以面向对象的方式组织代码(如中所述)。然而,在我的例子中,这是指窗口对象。因此我得到了错误

未捕获的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();

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

requestAnimationFrame(this.render.bind(this));
或者,你可以这样做

var context = this;
requestAnimationFrame(function() {
  context.render();
});
或者您可以避免创建自由变量并使用

或者,如果您使用的是ES6,则可以使用箭头函数

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

您可以做的另一个简单的改进是将render元素传递到应用程序构造函数中

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

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

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

requestAnimationFrame(this.render.bind(this));
或者,你可以这样做

var context = this;
requestAnimationFrame(function() {
  context.render();
});
或者您可以避免创建自由变量并使用

或者,如果您使用的是ES6,则可以使用箭头函数

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

您可以做的另一个简单的改进是将render元素传递到应用程序构造函数中

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

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

让我们来谈谈这个、上下文和函数

考虑它的一个好方法是,
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();
    });
}

将函数作为参数传递时要记住的一点是,您正在传递对函数的引用。函数本身不绑定到它可能是其方法的对象。

让我们来谈谈
这个
、上下文和函数

考虑它的一个好方法是,
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();
    });
}
将函数作为参数传递时要记住的一点是,您正在传递对函数的引用。函数本身不绑定到它可能是方法的对象