首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在对象函数中引用对象数据?

如何在对象函数中引用对象数据?
EN

Stack Overflow用户
提问于 2019-05-23 05:00:14
回答 3查看 59关注 0票数 0

我正在尝试制作一个简单的tic tac toe游戏来学习和练习JavaScript OOP,但遇到了一些困难。

我想在触发game.handleClick函数时引用game.turn值。我知道使用this关键字引用被调用的对象的作用域,而在handleClick中,this引用被单击的game-tile-x。如何引用'handleClick‘函数作用域之外的对象值?

任何帮助都将不胜感激!

代码语言:javascript
复制
<div id="game-board">
    <div id="game-tile-1" class="game-tile"></div>
    <!-- divs 2-8 -->
    <div id="game-tile-9" class="game-tile"></div>
</div>
代码语言:javascript
复制
function Game() {
    this.tiles = document.getElementsByClassName('game-tile'),
    this.turn = 0;

    this.init = function() {
        for (let i = 0; i < this.tiles.length; i++) {
            // reset game tiles
            this.tiles[i].innerHTML = '';

            // setup event listeners
            this.tiles[i].addEventListener('click', this.handleClick);
        }
    };
    this.handleClick = function() {
        let id = parseInt(this.id.replace('game-tile-', ''));
        console.log(id); // returns 0, 1, 2, etc.
        console.log(this.turn); // returns undefined
    };
}

let game = new Game();
game.init();
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-05-23 05:17:22

这里有一个基本的解决方案

代码语言:javascript
复制
function Game() {
    this.tiles = document.getElementsByClassName('game-tile'),
    this.turn = 0;

    this.init = function() {
        let tile;
        for (let i = 0; i < this.tiles.length; i++) {
            tile = this.tiles[i];
            // reset game tiles
            tile.innerHTML = '';

            // setup event listeners
            // don't mix this for the node & this for the game
            // let's bind the context to the game, and the first param to the tile
            tile.addEventListener('click', handleClick.bind(this, tile));
        }
    };

    function handleClick(tile) {
        let id = parseInt(tile.id.replace('game-tile-', ''));
        console.log(id); // returns 0, 1, 2, etc.
        console.log(this.turn); // returns undefined
    };
}

let game = new Game();
game.init();
票数 1
EN

Stack Overflow用户

发布于 2019-05-23 05:11:45

您可以使用curried函数,并使用游戏实例(this)调用外部函数,然后可以在内部使用它:

代码语言:javascript
复制
 this.tiles[i].addEventListener('click', this.handleClick(this));

 //...

this.handleClick = function(game) {
 return function() {
    let id = parseInt(this.id.replace('game-tile-', ''));
    console.log(id); // returns 0, 1, 2, etc.
    console.log(game.turn); 
 };
};
票数 1
EN

Stack Overflow用户

发布于 2019-05-23 05:11:54

有两种方法可以做到这一点,要么将this保存到稍后要用到的变量中(我们称之为闭包):

例如:

代码语言:javascript
复制
const self = this;
this.handleClick = function() {
    const id = parseInt(this.id.replace('game-tile-', ''));
};

或者调用bind,将函数的this对象绑定到当前作用域的this

代码语言:javascript
复制
this.handleClick = function() {
    const id = parseInt(this.id.replace('game-tile-', ''));
};
this.handleClick = this.handleClick.bind(this);

PS:

如果可以使用ES6箭头函数:

代码语言:javascript
复制
this.handleClick = () => {
    // this will point to the scope where the function is declared
}

如果可以使用ES6类:

代码语言:javascript
复制
class Game(){
    constructor(){
        this.tiles = document.getElementsByClassName('game-tile'),
        this.turn = 0;
        for (let i = 0; i < this.tiles.length; i++) {
        // reset game tiles
        this.tiles[i].innerHTML = '';

        // setup event listeners
        this.tiles[i].addEventListener('click', this.handleClick);
    }

    handleClick = () => {
        let id = parseInt(this.id.replace('game-tile-', ''));
        console.log(id); // returns 0, 1, 2, etc.
        console.log(this.turn); // returns undefined
    }
}

最好使用ES6语法,因为它对阅读器和机器都更容易理解。如果你担心浏览器的兼容性,可以使用像BabelJS这样的转译器

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56264956

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档