问题
I am trying to understand why using function() inside a computed property works, but a fat arrow does not.
Here is a class I created, and two definitions of computed properties, one passing in function() {} (foo) , and the other passing in () => {} bar. I included both styles being passed into an array forEach() also for reference (foo1, and bar1).
Can someone explain what is going on in each of these four instances?
import Ember from 'ember';
const Light = Ember.Object.extend({
isOn: false,
color: 'red',
foo: Ember.computed( 'isOn', 'color', function() {
console.log(`this in foo is ${this}`);
}) ,
foo1: [1].forEach(function() {
console.log(`this in foo1 is ${this}`);
}) ,
bar: Ember.computed( 'isOn', 'color', () => {
console.log(`this in bar is ${this}`);
}),
bar1: [1].forEach( () => {
console.log(`this in bar1 is ${this}`);
})
});
export default Ember.Controller.extend({
appName: 'Ember Twiddle',
init() {
this._super();
this.set('bulb', Light.create());
}
});
here is the template that references the all 4 properties
<h1>Welcome to {{appName}}</h1>
<br>
<br>
{{outlet}}
<br>
<br>
<p> the bulb is {{bulb.isOn}} </p>
<p> the bulb is {{bulb.foo}} </p>
<p> the bulb is {{bulb.foo1}} </p>
<p> the bulb is {{bulb.bar}} </p>
<p> the bulb is {{bulb.bar1}} </p>
and here are the results printed to the console.
DEBUG: -------------------------------
VM66 ember.debug.js:6395 DEBUG: Ember : 2.4.4
VM66 ember.debug.js:6395 DEBUG: Ember Data : 2.4.3
VM66 ember.debug.js:6395 DEBUG: jQuery : 1.11.3
VM66 ember.debug.js:6395 DEBUG: -------------------------------
VM70 about:srcdoc:29 this in foo1 is undefined
VM70 about:srcdoc:35 this in bar1 is undefined
VM70 about:srcdoc:26 this in foo is <(unknown mixin):ember360>
VM70 about:srcdoc:32 this in bar is undefined
Here is the link to the twiddle https://ember-twiddle.com/d5905b42eff57e8ad5c99a27a3199429?openFiles=templates.application.hbs%2C
回答1:
Your functions of the form
foo1: [1].forEach(function() {
console.log(`this in foo1 is ${this}`);
are not computed functions, as you probably know; they are executed at parse time. The value returned by forEach is undefined Therefore, the value of the foo1 property will be the constant undefined. The console log will happen exactly once, when the definition is parsed, before a Light object is even instantiated.
Your function
bar: Ember.computed( 'isOn', 'color', () => {
console.log(`this in bar is ${this}`);
}),
does not work because arrow functions have lexical this (in other words, the this of the surroundings). The this will be the this in effect at the time the definition is parsed, which is likely to be either undefined or window. Ember invokes the functions specified as part of computed properties in the context (with the this) of the object in question, so obviously having a this equal to undefined won't work at all.
来源:https://stackoverflow.com/questions/36613693/how-is-the-a-value-of-this-in-ember-js-computed-property-defined