我在使用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').click(function(dog) { // dog is passed in the function
console.log(dog); // Syntax error, unrecognized expression: #[object Object]
$('#' + dog).css('display, 'none');
});
}
}
当我不将狗传入点击功能时:我得到:
$('#puppy').click(function() {
console.log(dog) // (12) main.js:122k4c812e3a7275e10331000000 - this is the last value in the array - from safari console
$('#' dog).css('display', 'none);
}
有没有人有任何建议让每个元素都传递给click函数? 或者我是否错误地调用css方法来隐藏这些div?
答案 0 :(得分:4)
Closures绑定整个函数的作用域,而不是单个变量或值。
以此代码为例:
function foo() {
var i, func;
for (i = 0; i < 10; ++i) {
if (i == 0) {
func = function () {
alert(i);
}
}
}
func();
}
foo();
您可能希望foo
导致0
收到提醒。但是,自创建分配给i
的函数以来,func
的值已更改;拨打func
提醒“10”。
这是另一个说明这个概念的例子:
function foo() {
var i = 42;
function func() {
alert(i);
}
for (i = 0; i < 10; ++i) {
// do nothing
}
func();
}
foo();
尝试弄清楚会发出什么警报,并将代码作为测试运行。
第二个问题是变量是在函数范围内绑定的(而不是你期望的块范围)。
拿这段代码:
function foo() {
var i;
for (i = 0; i < 10; ++i) {
var j = i;
}
alert(j);
}
foo();
您可能希望此代码警告“未定义”,抛出运行时错误,甚至抛出语法错误。但是,“10”会被警告。为什么?在JavaScript中,上述代码被有效地翻译成:
function foo() {
var i;
var j;
for (i = 0; i < 10; ++i) {
j = i;
}
alert(j);
}
foo();
从这个例子中可以更清楚地看到“10”确实被警告了。
那么你如何解决问题呢?最简单的方法是改变你的逻辑:不是每只狗附加一个事件处理程序,每个狗集合攻击一个事件处理程序。例如:
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');
}
});
}
如果您对现有代码的“正确”转换感兴趣(即具有相同的行为,除了修复了错误),我也可以举例说明。但是,我上面给出的解决方案是一个更好的解决方案,可以使代码更清晰。
答案 1 :(得分:2)
您忘了关闭报价。这样:
$('#' + dog).css('display, 'none');
应该是:
$('#' + dog).css('display', 'none');
您的脚本存在一些问题。我将专注于循环的整体逻辑结构。
不要将许多处理程序附加到.click()
,而是使用jQuery的 .each()
附加一个迭代JSON的处理程序。 .each()
回调的第一个参数是索引号,第二个参数是值。您可以通过命名参数或使用arguments[0]
和arguments[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/>");
});
});
}
答案 2 :(得分:1)
为什么不给小狗一个班级.dog
并在点击#puppy
时隐藏它们?
$("#puppy").click(function() {
$(".dog").hide();
});
或者因为你的狗的ID似乎以k开头,你可能会考虑这样的事情:
$("#puppy").click(function() {
// hide everything with ID beginning with 'k'
$('[id^=k]').hide();
});
答案 3 :(得分:0)
你不能像在那里那样将dog值传递给jquery click事件。点击功能签名是:
$(object).click(function(){
});
你不能像这样经过狗。即使函数期望参数,命名它也会导致问题。您可能需要将dog的值存储在更全局的范围内,以便在单击事件发生时,您仍然可以访问它。