Javascript变量范围问题
我无法用javascript解决范围问题。 我有一个数组dog[],它是从JSON定义的,我需要从嵌套函数内部访问它Javascript变量范围问题,javascript,jquery,variables,scope,Javascript,Jquery,Variables,Scope,我无法用javascript解决范围问题。 我有一个数组dog[],它是从JSON定义的,我需要从嵌套函数内部访问它 function blah(json) { for (var u = 0; u < json[0][1][u].length; u ++ ) { var dog = 'k' + json[0][1][u].doggies; console.log(dog); // prints array of doggie strings $('#puppy')
function blah(json) {
for (var u = 0; u < json[0][1][u].length; u ++ ) {
var dog = 'k' + json[0][1][u].doggies;
console.log(dog); // prints array of doggie strings
$('#puppy').click(function(dog) { // dog is passed in the function
console.log(dog); // Syntax error, unrecognized expression: #[object Object]
$('#' + dog).css('display, 'none');
});
}
}
是否有人建议将数组中的每个元素都传递到click函数中?
还是我错误地调用css方法来隐藏那些div?您不能像在jquery click事件中那样将dog值传递给该事件。单击功能签名为:
$(object).click(function(){
});
你不能这样把狗递进来。即使函数需要一个参数,将其命名为dog也会引起问题。您可能需要将dog的值存储在一个更全局的范围内,这样当单击事件发生时,您仍然可以访问它。为什么不给doggies一个类
。dog
并在单击#puppy
时隐藏它们
$("#puppy").click(function() {
$(".dog").hide();
});
<> P>或者因为你的狗的ID似乎从K开始,你可能会考虑这样的事情:
$("#puppy").click(function() {
// hide everything with ID beginning with 'k'
$('[id^=k]').hide();
});
问题1
闭包绑定整个函数的作用域,而不是单个变量或值
以这段代码为例:
function foo() {
var i, func;
for (i = 0; i < 10; ++i) {
if (i == 0) {
func = function () {
alert(i);
}
}
}
func();
}
foo();
function blah(json) {
$('#puppy').click(function () {
var u, dog;
for (u = 0; u < json[0][1][u].length; u++) {
dog = 'k' + json[0][1][u].doggies;
console.log(dog);
$('#' + dog).css('display', 'none');
}
});
}
试着找出什么会被警告,并将代码作为测试运行
问题2
第二个问题是变量绑定在函数范围(而不是您所期望的块范围)
以这个代码为例:
function foo() {
var i;
for (i = 0; i < 10; ++i) {
var j = i;
}
alert(j);
}
foo();
函数foo(){
var i;
对于(i=0;i<10;++i){
var j=i;
}
警惕(j);
}
foo();
您可能期望此代码发出“未定义”警报,抛出运行时错误,甚至抛出语法错误。但是,“10”已发出警报。为什么?在JavaScript中,上述代码被有效地转换为:
function foo() {
var i;
var j;
for (i = 0; i < 10; ++i) {
j = i;
}
alert(j);
}
foo();
函数foo(){
var i;
var j;
对于(i=0;i<10;++i){
j=i;
}
警惕(j);
}
foo();
从这个例子中可以更清楚地看到,“10”确实被警告了
解决方案
那么你如何解决你的问题呢?最简单的方法是改变你的逻辑:不是为每只狗附加一个事件处理程序,而是为每只狗的集合攻击一个事件处理程序。例如:
function foo() {
var i, func;
for (i = 0; i < 10; ++i) {
if (i == 0) {
func = function () {
alert(i);
}
}
}
func();
}
foo();
function blah(json) {
$('#puppy').click(function () {
var u, dog;
for (u = 0; u < json[0][1][u].length; u++) {
dog = 'k' + json[0][1][u].doggies;
console.log(dog);
$('#' + dog).css('display', 'none');
}
});
}
函数blah(json){
$('#puppy')。单击(函数(){
var u,狗;
对于(u=0;u
如果您对现有代码的“适当”转换感兴趣(即,除了修复错误外,具有相同的行为),我也可以给您举一个例子。但是,我上面给出的解决方案是一个更好的解决方案,并且代码更干净。重要注意事项:
你忘记关闭你的报价了。这:
$('#' + dog).css('display, 'none');
应该是:
$('#' + dog).css('display', 'none');
改进的循环: 您的脚本有几个问题。我将集中讨论循环的总体逻辑结构 不要将许多处理程序附加到
。单击()
,只需附加一个使用jQuery的在JSON上迭代的处理程序即可。.each()
回调的第一个参数是索引号,第二个参数是值。您可以通过命名参数或使用参数[0]
和参数[1]
来使用这两个参数。我在下面展示前一种方法:
出于演示目的,我添加了更多的测试输出:
function blah(json) {
$('#puppy').click(function() {
// iterate over each json[0][1]
$.each(json[0][1], function(index, value) {
// Your original 2 lines
console.log(value);
$('#' + value).css('display', 'none');
// This is just test output, so you can see what is going
// on.
$("body").append("Number " + index + " is " + value ".<br/>");
});
});
}
函数blah(json){
$('#puppy')。单击(函数(){
//迭代每个json[0][1]
$.each(json[0][1],函数(索引,值){
//你原来的两行
console.log(值);
$('#'+value).css('display','none');
//这只是测试输出,所以您可以看到发生了什么
//开。
$(“正文”)。追加(“数字”+索引+”是“+值”。
);
});
});
}
对不起,但是不json[0][1][u]。长度随着u
的每次迭代而变化?彼得·阿杰泰,我在回答中已经提到了这一点@罗布斯托,抓得好;不知道那里发生了什么跟踪。。。。但是在本例中,dog
作为一个参数实际上代表了事件
,因为它是中回调的第一个参数;我误解了你的答案。(我漏掉了两个词,这完全失去了意义…我的错!)在中回调的第一个参数。click()
是发生的事件,因此您应该从函数(dog)中删除dog
{
在您的解决方案中…为了不混淆问题。非常感谢!非常有用的解释。当我睡眠不足较少时,我将更深入地研究您的示例。@Peter Ajtai,感谢您捕捉到这一点。我复制粘贴了原始代码,基本上只交换了两行。我会修复它。与所有人相比,这是一个简单的解决方案else.+1用于将CSS类用作选择器。