ES6。从outsite类访问类变量

时间:2017-04-24 11:53:52

标签: javascript html ecmascript-6

我在从班级以外获得某些变量的价值时遇到了问题。 我想访问attack但由于某种原因它未定义。有人可以帮我吗?

CODE:

index.js(我尝试访问该变量)

import $ from 'jquery';
import Tone from 'tone'; 
import EnvelopeModule from './envelope.js';

$(document).ready(() => {

  const envelope = new EnvelopeModule();
  console.log(envelope.attack); //undefined

  initApp();
});

envelope.js(我设置变量的地方)

import $ from 'jquery';
import Tone from 'tone';

export default class EnvelopeModule {
  constructor(attack) {
    this.attack = attack;
    this.init();        
  }

  init() {
    this.addListeners();
  }

  addListeners() {
    $('input#attack').on('input change', this.set);
  }

  set() {
    this.attack = $('input#attack').val()/100;
    let val = $(this).val()/100;
    $(this).prev().text(val);
  }
}

1 个答案:

答案 0 :(得分:2)

You send your friend to the post office to pick up a package. As soon as he steps out the door, you call his cell phone and ask, "Hey, what was in that package?" Your friend answer, "I have no idea. I'm not at the post office yet." You could call your friend every ten minutes and see if he got it yet, but that's a bad idea because

  1. it will eat up time that your friend could be doing something useful, and
  2. it could cause a delay: if you call again right before he gets the package, you wait another nine minutes before you find out what's in the package

Instead, you tell your friend call you as soon as he gets the package. There's no wasted time, and you find out what's inside as soon as he picks it up.

So, what does that story have to do with your code?

The attack property only holds a meaningful value when an input or change event takes place on input#attack element. You're asking for the attack value immediately, before any meaningful event has taken place. Instead, you can simply wait: attack holds a meaningful value only when your set function runs.

If you want index.js to specify some arbitrary code to run every time attack changes, you can do this by passing a function as an argument to your constructor:

export default class EnvelopeModule {
  constructor(attack, runMeWhenAttackChanges) {
    this.attack = attack;
    this.runMeWhenAttackChanges = runMeWhenAttackChanges;
    this.init();        
  }

  init() {
    this.addListeners();
  }

  addListeners() {
    $('input#attack').on('input change', this.set.bind(this));
  }

  set(e) {
    this.attack = $(e.currentTarget).val()/100;
    let val = $(e.currentTarget).val()/100;
    $('input#attack').prev().text(val);
    this.runMeWhenAttackChanges();
  }
}

(Note that I fixed an error in how you were handling this in addListeners and set.)

Then, inside your index.js provide that runMeWhenAttackChanges function:

const envelope = new EnvelopeModule(undefined, function() {
    console.log(this.attack);
});

The value of this.attack will be meaningful only inside the callback function. Any operations that require the most recent value of attack should be run from inside that callback. This callback does not run immediately, and it may run many times, long after the surrounding code has finished. You can think of this callback as a set of instructions to run every time attack changes, and we've encapsulated those instructions in a function. (To go back to the original metaphor, this is your friend calling you each time he picks up a package.)