【发布时间】:2016-09-02 22:58:03
【问题描述】:
变量 cont 在以下内容中丢失:
__factory.setupMenu = function(cont,input,multiSelect,exclusive,popMenu){
var __menu = {multiSelect:multiSelect};
spotter.events.setEventTrigger(input,'change');
__menu.exclusive = {inputs:[],values:exclusive||[],simpleValues:[]};
alert(cont);//<-- is defined here
window.popSelectComponent= cont;//<-- saved it globally to test reference
return function(ajaxResult){
var data = ajaxResult.template.response||[];
var info = {},l=data.length;
while(--l > -1){
info[String(data[l].value)] = data[l].abbr||data[l].name;
}
var textTarget;
alert(window.popSelectComponent);//<-- this is defined as expected
alert(cont);//<-- is now undefined
alert(input);//<-- this is defined as expected
if(!(textTarget = cont.querySelector('[data-pop-selected]'))){textTarget = cont;}
if(!input.popSelectTemplate){
spotter.data.bindElementToInput(textTarget,input,function(content){
content = content.split(',');
var l=content.length;
while(--l > -1){
content[l] = info[content[l]];
}
content = content.join(',');
return (content.length ? content : 'ignore');
});
}
else{
var cont = document.createElement('SPAN');//<-- PROBLEM IS CAUSED HERE. HOISTING IS CAUSING CONT TO BE UNDEFINED AT CLOSURE START
cont.className="multi-select";
cont.appendChild(cont);
//removal function
var remove = (function(input){
return function(e){
var evt = e ? e:window.event;
if (evt.stopPropagation) evt.stopPropagation();
if (evt.cancelBubble!=null) evt.cancelBubble = true;
if(input.value !== input.spotterPopSelectDefaultValue){
input.value = input.value.removeListValue(this.getAttribute('data-id'),',');
spotter.deleteElement(this);
if(input.value === '' && input.value !== input.spotterPopSelectDefaultValue){
input.value = input.spotterPopSelectDefaultValue;
input.eventTriggers['pop-select-change']();
}
}
};
}(input));
input.spotterPopMenuOptions = __menu;
input.addEventListener('pop-select-change',(function(cont, info, template){
return function(){
var HTML = '';
this.value.split(',').forEach(function(val){
HTML += template.replace('$[ID]', val).replace('$[NAME]', info[val]);
});
cont.innerHTML = HTML;
spotter.castToArray(cont.children).forEach(function(el){ console.log('option el',el); el.addEventListener('click',remove,false); });
console.log('input.spotterPopMenuOptions',input.spotterPopMenuOptions);
};
}(cont, info, input.popSelectTemplate.innerHTML)),false);
}
....
所以运行var func = __factory.setupMenu(...)({template:{}}) 我收到一条错误消息,提示 cont 未定义,而 window.popSelectComponent 的定义如预期。我尝试更改 cont 的名称,以为我忽略了一些正在改变值但也不起作用的东西。
运行该函数后,我在最初创建此闭包的上下文中检查 cont 并且 cont 仍被定义,因此据我所知,这不是对象引用丢失的问题。
【问题讨论】:
-
尝试
console.log(...)而不是使用警报。它会让你的生活更轻松,你不会后悔的。 -
您的代码实际上在该函数中是否有
alert(cont),或者您是否尝试在调试时在控制台中运行它。我怀疑发生了这样的事情:stackoverflow.com/a/21918024/1715579 -
我只添加了警报来测试价值,因为我目前正在运行大量的 console.log 消息:P
-
@p.s.w.g 不是这样,因为他确实在闭包的最后一行使用了
cont。 -
这看起来很棘手。您可以制作一个 jsfiddle 或提供一个指向实时站点的链接吗?
标签: javascript closures