我想基于构造函数参数创建一些对象成员,但是它没有按预期工作。没有成员被创建。我怎样才能做到这一点?
function Foo(parameters = []) {
parameters.forEach(function(e) {
this[e.name] = e.initial;
});
};
const p = [{
"name": "sensitivity",
"initial": 50
}];
const f = new Foo(p);
答案 0 :(得分:4)
您在this
方法提供的回调功能中使用forEach
关键字,但该功能的this
只是参考< / strong>到窗口对象。
您可以在此answer.
中详细了解javascript中this
的范围
bind
方法。bind()方法创建一个新函数,当被调用时,它具有它 此关键字设置为提供的值,具有给定的序列 调用新函数时提供的任何参数。
function Foo(parameters = []) {
parameters.forEach(function(e) {
this[e.name] = e.initial;
}.bind(this));
};
const p = [{
"name": "sensitivity",
"initial": 50
}];
const f = new Foo(p);
console.log(f);
arrow
函数。在arrow
个函数之前,每个new
函数都定义了自己的this
值。
例如,this
在构造函数的情况下可以是新对象。
function Person(age){
this.age=age;
console.log(this);
}
let person=new Person(22);
如果创建的函数可以像this
那样访问,那么base
可以指向到obj.getAge()
对象。
let obj={
getAge:function(){
console.log(this);
return 22;
}
}
console.log(obj.getAge());
arrow
函数不会创建自己的this
,它只使用this
执行enclosing
的{{1}}值。另一方面,context
函数使用父范围的arrow
。
this
答案 1 :(得分:1)
你有经典&#34; this
不是你认为的那样&#34;问题。使用箭头函数是解决问题的一种方法,因为它保留了父范围的this
引用。
function Foo(parameters = []) {
parameters.forEach(e => this[e.name] = e.initial);
};
const p = [{
"name": "sensitivity",
"initial": 50
}];
const f = new Foo(p);
console.log(f);
&#13;
答案 2 :(得分:1)
您遇到的问题是this
的问题。
您在回调中的函数内部引用this
,但该内部函数的this
引用parameters
对象而不是Foo
实例。
例如,如果您在循环后添加:
console.log(parameters)
我怀疑您会发现parameters
对象本身已被修改为具有值'50'
的名称属性。
有几种方法可以解决这个问题,而这些方法都与保留正确的预期有关。
将循环函数改为lambda函数而不是像这样的基本函数:
parameters.forEach((e) => {
this[e.name] = e.initial;
});
lambda函数和标准函数之间的主要区别在于lambda函数会自动保留其父作用域的this
。
您还可以绑定函数以使用特定的this
而不是默认值,即调用者对象。
parameters.forEach((function (e) {
this[e.name] = e.initial;
}).bind(this));
在函数上调用.bind(obj)
将返回一个新函数,其中obj
在调用时始终为this
。
将外部范围中的this
设置为自己的变量并直接引用它也很常见。
var self = this;
parameters.forEach(function (e) {
self[e.name] = e.initial;
});
这些是正确捕获和使用this
的基本方法。
我还想补充一点,除了您遇到的this
错误之外,您可能想要完全考虑采用不同的方法来实现目标。具体而言,您可能需要考虑使用Object.assign
来获取您正在寻找的行为。这可能如下所示:
const f = new Foo(p)
Object.assign(f, { sensitivity: 50 })