我在从班级以外获得某些变量的价值时遇到了问题。
我想访问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);
}
}
答案 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
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.)