JS class - 'this' 在承诺中未定义
JS class - 'this' is undefined in promise
有一个 Class 里面如果这个 class 我正在尝试填充一个数组 winch 定义在 'constructor'.
class ClassA {
constructor(){
...
this.place = [];
}
fillUp() {
fetch(path)
.then(function(response) {
return response.json();
}).then(function(result) {
this.place.push({"result":result})
})
}
}
inst = new ClassA();
inst.fillUp();
结果我得到了这个错误:类型错误:无法读取未定义的 属性 'place'。
问题出在哪里?
this
在 javascript 中很奇怪。根据对对象调用 code/function 的方式,它可能 return 值不是您所期望的。如果您使用的是现代 javascript,则应使用短箭头表示法。这将保留 this
绑定的内容。否则,您必须将 .bind(this)
添加到您引用 this
:
的函数中
fetch(path)
.then((response)=>{
return response.json();
}).then((result)=>{
this.place.push({"result":result})
})
使用箭头函数。
class ClassA {
constructor(){
...
this.place = [];
}
fillUp = () => {
fetch(path)
.then(function(response) {
return response.json();
}).then(function(result) {
this.place.push({"result":result})
})
}
}
inst = new ClassA();
inst.fillUp();
承诺处理程序是具有不同 this
值的不同函数。
要使 this
内部相等,您可以使用箭头函数,它从定义它们的地方继承 this
:
class ClassA {
constructor(){
...
this.place = [];
}
fillUp() {
fetch(path)
.then(response => response.json())
.then(result => {
this.place.push({"result":result})
})
}
}
inst = new ClassA();
inst.fillUp();
或者,.bind()
函数:
class ClassA {
constructor(){
...
this.place = [];
}
fillUp() {
fetch(path)
.then(function(response) {
response.json()
})
.then((function(result) {
this.place.push({"result":result})
}).bind(this))
}
}
inst = new ClassA();
inst.fillUp();
您可以通过在尝试 push
到数组的回调中使用 arrow function expression 来解决您的问题。使用典型函数表达式的问题是它创建了自己的 this
关键字绑定。另一方面,箭头函数:
An arrow function does not have its own this
. The this
value of the
enclosing lexical scope is used; arrow functions follow the normal
variable lookup rules. So while searching for this
which is not
present in current scope, an arrow function ends up finding the this
from its enclosing scope.
因此,如果您在回调中使用箭头函数,该函数将从它的封闭范围(即:ClassA
对象)中获取 this
。
这是它如何工作的演示:
const mockFetch = new Promise((resolve, reject) => {
console.log('Fetching data..please wait..')
setTimeout(() => resolve({
json: () => '{ data: \'Some response data\'}'
}), 1500)
});
class ClassA {
constructor() {
this.place = [];
}
fillUp() {
mockFetch.then(function(response) {
return response.json();
}).then(result => {
this.place.push({
"result": result
});
console.log(this.place);
})
}
}
inst = new ClassA();
inst.fillUp();
.then((result) => {
this.place.push({"result":result})
})
效果很好。比你!
有一个 Class 里面如果这个 class 我正在尝试填充一个数组 winch 定义在 'constructor'.
class ClassA {
constructor(){
...
this.place = [];
}
fillUp() {
fetch(path)
.then(function(response) {
return response.json();
}).then(function(result) {
this.place.push({"result":result})
})
}
}
inst = new ClassA();
inst.fillUp();
结果我得到了这个错误:类型错误:无法读取未定义的 属性 'place'。 问题出在哪里?
this
在 javascript 中很奇怪。根据对对象调用 code/function 的方式,它可能 return 值不是您所期望的。如果您使用的是现代 javascript,则应使用短箭头表示法。这将保留 this
绑定的内容。否则,您必须将 .bind(this)
添加到您引用 this
:
fetch(path)
.then((response)=>{
return response.json();
}).then((result)=>{
this.place.push({"result":result})
})
使用箭头函数。
class ClassA {
constructor(){
...
this.place = [];
}
fillUp = () => {
fetch(path)
.then(function(response) {
return response.json();
}).then(function(result) {
this.place.push({"result":result})
})
}
}
inst = new ClassA();
inst.fillUp();
承诺处理程序是具有不同 this
值的不同函数。
要使 this
内部相等,您可以使用箭头函数,它从定义它们的地方继承 this
:
class ClassA {
constructor(){
...
this.place = [];
}
fillUp() {
fetch(path)
.then(response => response.json())
.then(result => {
this.place.push({"result":result})
})
}
}
inst = new ClassA();
inst.fillUp();
或者,.bind()
函数:
class ClassA {
constructor(){
...
this.place = [];
}
fillUp() {
fetch(path)
.then(function(response) {
response.json()
})
.then((function(result) {
this.place.push({"result":result})
}).bind(this))
}
}
inst = new ClassA();
inst.fillUp();
您可以通过在尝试 push
到数组的回调中使用 arrow function expression 来解决您的问题。使用典型函数表达式的问题是它创建了自己的 this
关键字绑定。另一方面,箭头函数:
An arrow function does not have its own
this
. Thethis
value of the enclosing lexical scope is used; arrow functions follow the normal variable lookup rules. So while searching forthis
which is not present in current scope, an arrow function ends up finding thethis
from its enclosing scope.
因此,如果您在回调中使用箭头函数,该函数将从它的封闭范围(即:ClassA
对象)中获取 this
。
这是它如何工作的演示:
const mockFetch = new Promise((resolve, reject) => {
console.log('Fetching data..please wait..')
setTimeout(() => resolve({
json: () => '{ data: \'Some response data\'}'
}), 1500)
});
class ClassA {
constructor() {
this.place = [];
}
fillUp() {
mockFetch.then(function(response) {
return response.json();
}).then(result => {
this.place.push({
"result": result
});
console.log(this.place);
})
}
}
inst = new ClassA();
inst.fillUp();
.then((result) => {
this.place.push({"result":result})
})
效果很好。比你!