Javascript 未通过应用或调用将其设置为值
Javascript not setting this to value with apply or call
编辑:下面的代码是当场编造的,以展示我是如何处理我正在做的事情的。它肯定不会 运行,它缺少很多东西。
这是 codepen 中的一个工作示例:https://codepen.io/goducks/pen/XvgpYW
更短的示例:https://codepen.io/goducks/pen/ymXMyB
创建使用 call 或 apply 的函数时,使用 getPerson 时 this 值保持为空。但是,当我使用 apply 或调用 getPerson 时,它 return 是正确的人选。
大家多多批评指正,我真的是学的越来越多了。我正处于项目部分的中间,因此可能很难更改所有代码,但我的下一个项目可以更好地实现这一点。
调用和应用设置为 window 而不是对象。
我将提供更简单的代码,与我正在谈论的概念相同。
function createPerson(){
this.manager = null;
this.teamManager = null;
this.setTeamManager = function(val){
this.teamManager = val;
}
this.setManager = function(val){
console.log('setting manager to',val);
this.teamManager = val;
}
this.getTeamManager = function(){
console.log('setting team manager to',val);
return this.teamManager ;
}
this.getManager = function(){
return this.manager;
}
this.appendSelect = function(elem){
var that = this;
createOtherSelects(that,elem);
}
//some functions that create selects with managers etc
//now assume there are other selects that will filter down the teams,
//so we might have a function that creates on change events
function createOtherSelects(that){
//code that creates locations, depending on location chosen will
//filter the managers
$('#location').on('change',function(){
//do some stuff
//... then call create management
createManagement(that,elem);
});
}
function createManagement(that,elem){
var currentLocation = that.location; //works
var area = that.area;//works ... assume these are set above
//code that returns a filter and unique set of managers back
that.teamManager = [...new Set(
data.map(person=>{
if(person.area==area &&
person.currentLocation==currentLocation
){
return person;
}
})
)].filter(d=>{if(d){return d}});
if(elem.length>0){
var selectNames = ['selectManager','selectTeamManager'];
var fcns = [that.setManager,that.setTeamManager];
for(var i = 0; i < selectNames.length;i++){
//do stuff
if(certainCriteriaMet){
// filter items
if(filteredManager == 1){
fcns[i].call(null,currentManager);//
}
}
}
}
}
}
var xx = new createPerson()
在控制台中,我看到 setting manager 和 setting team manager 具有正确的值。
然而,当我在控制台中调用 xx 时,我看到除了
xx.teamManager 和 xx.manager
而是应用于 window,因此如果我在控制台中键入 teamManager,它会 return 与正确的人。
如果我直接说
that.setManager('Steve')
甚至它工作得很好。
xx.setManager('steve')
setManager 中的 this 值以某种方式从对象的当前实例更改为 this window。不知道为什么,想学学apply和call的用法,以供日后参考。
我认为问题出在您的以下代码上
fcns[i].call(null,currentManager)
如果您不提供 "this" 调用,它将在非严格模式下替换为全局对象。
fcns[i].call(that,currentManager)
参见 mdn 文章 here
根据您的代码笔示例,您需要更改该行
fcnset[0].apply(that,[randomName]);
apply
方法的第一个参数是上下文,如果你没有给它你的方法的上下文,它默认使用全局上下文。这就是为什么你最终改变了 window
对象,而不是你想要的对象!
编辑:下面的代码是当场编造的,以展示我是如何处理我正在做的事情的。它肯定不会 运行,它缺少很多东西。 这是 codepen 中的一个工作示例:https://codepen.io/goducks/pen/XvgpYW
更短的示例:https://codepen.io/goducks/pen/ymXMyB
创建使用 call 或 apply 的函数时,使用 getPerson 时 this 值保持为空。但是,当我使用 apply 或调用 getPerson 时,它 return 是正确的人选。
大家多多批评指正,我真的是学的越来越多了。我正处于项目部分的中间,因此可能很难更改所有代码,但我的下一个项目可以更好地实现这一点。
调用和应用设置为 window 而不是对象。 我将提供更简单的代码,与我正在谈论的概念相同。
function createPerson(){
this.manager = null;
this.teamManager = null;
this.setTeamManager = function(val){
this.teamManager = val;
}
this.setManager = function(val){
console.log('setting manager to',val);
this.teamManager = val;
}
this.getTeamManager = function(){
console.log('setting team manager to',val);
return this.teamManager ;
}
this.getManager = function(){
return this.manager;
}
this.appendSelect = function(elem){
var that = this;
createOtherSelects(that,elem);
}
//some functions that create selects with managers etc
//now assume there are other selects that will filter down the teams,
//so we might have a function that creates on change events
function createOtherSelects(that){
//code that creates locations, depending on location chosen will
//filter the managers
$('#location').on('change',function(){
//do some stuff
//... then call create management
createManagement(that,elem);
});
}
function createManagement(that,elem){
var currentLocation = that.location; //works
var area = that.area;//works ... assume these are set above
//code that returns a filter and unique set of managers back
that.teamManager = [...new Set(
data.map(person=>{
if(person.area==area &&
person.currentLocation==currentLocation
){
return person;
}
})
)].filter(d=>{if(d){return d}});
if(elem.length>0){
var selectNames = ['selectManager','selectTeamManager'];
var fcns = [that.setManager,that.setTeamManager];
for(var i = 0; i < selectNames.length;i++){
//do stuff
if(certainCriteriaMet){
// filter items
if(filteredManager == 1){
fcns[i].call(null,currentManager);//
}
}
}
}
}
}
var xx = new createPerson()
在控制台中,我看到 setting manager 和 setting team manager 具有正确的值。
然而,当我在控制台中调用 xx 时,我看到除了 xx.teamManager 和 xx.manager
而是应用于 window,因此如果我在控制台中键入 teamManager,它会 return 与正确的人。
如果我直接说
that.setManager('Steve')
甚至它工作得很好。
xx.setManager('steve')
setManager 中的 this 值以某种方式从对象的当前实例更改为 this window。不知道为什么,想学学apply和call的用法,以供日后参考。
我认为问题出在您的以下代码上
fcns[i].call(null,currentManager)
如果您不提供 "this" 调用,它将在非严格模式下替换为全局对象。
fcns[i].call(that,currentManager)
参见 mdn 文章 here
根据您的代码笔示例,您需要更改该行
fcnset[0].apply(that,[randomName]);
apply
方法的第一个参数是上下文,如果你没有给它你的方法的上下文,它默认使用全局上下文。这就是为什么你最终改变了 window
对象,而不是你想要的对象!