苦苦挣扎让ES6这个绑定起作用

时间:2017-10-03 16:59:01

标签: javascript ecmascript-6 this bind arrow-functions

我写了这段代码,试图创造一个即兴格斗游戏。它使用旧样式函数关键字,因此当我想使用辅助函数isAlive时,我不得不做一个非常丑陋的'this'绑定。

我试图了解'this'与箭头函数的行为有何不同,但当我将第一行更改为ES6语法并删除绑定时,它总是返回false。

let isAlive = () => this.health > 0;

我做错了什么?我很确定语法本身就可以。

let isAlive = function () { return this.health > 0};

let getFighter = function (color, strength) {
    return {
        color: color,
        health: 100,
        strength: typeof strength !== 'undefined' ? strength : 1,
        attack: function (what) {
            hit_points = Math.floor(Math.random() * 10 * this.strength);
            document.writeln(this.color + ' fighter attacks ' + what.color + ' trying to deal ' + hit_points + ' damage.');
            what.get_hurt(hit_points);
        },
        get_hurt: function (hit_points) {
            if ( !isAlive.bind(this)() ) {
                document.writeln(this.color + ' fighter already dead!');
                document.writeln();
                return;
            } 
            this.health = this.health - hit_points;
            document.writeln(this.color + ' received ' + hit_points + ' damage and has ' + this.health + ' HP left.');
            if ( !isAlive.bind(this)() ) {
                document.writeln(this.color + ' fighter died!');
            }
            document.writeln();
        }
    };
};

blue = getFighter('Blue', 3);
red = getFighter('Red');


console.log(red);
console.log(blue);

while (isAlive.bind(blue)()) {
    red.attack(blue);
}

red.attack(blue)

3 个答案:

答案 0 :(得分:2)

箭头函数不创建它自己的,使用封闭执行上下文的这个值。

通过在不同的执行上下文中定义isAlive,您还可以将关键字绑定到不同的。

如果您想利用箭头功能,请在功能中声明它们

function foo(){
  const isAlive = () => this.health > 100;
}

在你的情况下,如果你想要一个帮助器,你要么将它声明为对象的一部分,要么使用ES6 Classes和class属性将为你做。

答案 1 :(得分:1)

查看您的代码示例,我认为我们首先需要了解this的工作原理。 this将引用已实例化的对象/函数。

const getFighter = function(color, strength) {
  this.color = color;
  this.strength = strength && 1;

  return {
    health: 100,
    isAlive: this.health > 0,
    hit_points: () => Math.floor(Math.random() * 10 * this.strength),
    attack: (what) => {
      document.writeln(`${this.color} fighter attacks ${what.color} trying to deal ${this.hit_points} damage.`);
      what.get_hurt(this.hit_points);
      return null;
    },
    get_hurt: () => {
      if (!this.isAlive) {
        document.writeln(`${this.color} fighter already dead!`);
        return;
      }
      this.health = this.health - this.hit_points;
      document.writeln(`${this.color} received ${this.hit_points} damage and has ${this.health} HP left.`);
      if (!this.isAlive) {
        document.writeln(`${this.color} fighter died!`);
      }
    },
  };
};


const BlueFighter = new getFighter("Blue", 3);
const RedFighter = new getFighter("Red");

console.log('is Alive', BlueFighter.isAlive);
console.log('Health:', RedFighter.health);

您可以看到我利用() =>,以便我可以访问该功能中的this。除非你.bind(this)

,否则你不会使用常规函数

答案 2 :(得分:0)

您可以在isAlive函数定义参数并将对象或this传递给函数



let isAlive = ({health}) => health > 0; 

let getFighter = function(color, strength) {
  return {
    color: color,
    health: 100,
    strength: typeof strength !== 'undefined' ? strength : 1,
    attack: function(what) {
      hit_points = Math.floor(Math.random() * 10 * this.strength);
      document.writeln(this.color + ' fighter attacks ' + what.color 
        + ' trying to deal ' + hit_points + ' damage.');
      what.get_hurt(hit_points);
    },
    get_hurt: function(hit_points) {
      if (!isAlive(this)) {
        document.writeln(this.color + ' fighter already dead!');
        document.writeln();
        return;
      }
      this.health = this.health - hit_points;
      document.writeln(this.color + ' received ' + hit_points 
        + ' damage and has ' + this.health + ' HP left.');
      if (!isAlive(this)) {
        document.writeln(this.color + ' fighter died!');
      }
      document.writeln();
    }
  };
};

blue = getFighter('Blue', 3);
red = getFighter('Red');

console.log(red);
console.log(blue);

while (isAlive(blue)) {
  red.attack(blue);
}

red.attack(blue);

console.log(red);
console.log(blue);