为什么我从 JSLint 获得从事件调用的函数的 "is out of scope"?
Why am I getting "is out of scope" from JSLint for a function called from an event?
我需要重新初始化来自两个不同事件(一个 html select 变化和一个复选框变化)的一些 html 元素的状态,所以我创建了一个我放置的函数在 "ready" 函数之外执行此操作,并从两个事件中调用它。
但是,JSLint 标记了对它的调用:
$('#unitsselect').change(function() {
unitSelected = true;
reinitializeRecipientsAndGenerateVals();
. . .
...作为 "out of scope";具体来说,它告诉我,
'reinitializeRecipientsAndGenerateVals' is out of scope.
并指出该行是有问题的行。
reinitializeRecipientsAndGenerateVals()
确实在 change 事件处理程序之外,也在 "ready" 函数之外。我将它放在就绪函数中以查看是否是问题所在,但我仍然从 JSLint 那里收到警告。
我怎样才能重用这个函数,这样我就不必在两个更改事件处理程序中移动它?
注意:This 有一个 "used out of scope" 部分,但没有 "is out of scope"
根据 this,所有版本的 JSLint 都使用“{a} 在绑定上下文之外使用”
更新
即使我将函数右移 到 更改事件处理程序中,JSLint 也会以同样的方式抱怨。
UDPATE 2
对于 Travis,这是整个辣酱玉米饼馅:
$(document).ready(function() {
var unitSelected = false;
var checkboxSelected = false;
// When unit is selected, populate the data range value elements; if checkbox selected,
// also populate email recipients and generate vals (specific day or based on a pattern)
$('#unitsselect').change(function() {
unitSelected = true;
reinitializeRecipientsAndGenerateVals();
var unitval = $('#unitsselect').val();
// This is admittedly kludgy - copying the same ajax call multiple times, changing only
// the report number; but a forloop attempt failed because of the asynchronous nature of
// it all; for some reason, populatedatarangeprams() was called only once, and with a
// rptval of 5 (when it "should have been" 1..4 instead).
var model = JSON.stringify({ unit: unitval, report: 1 });
$.ajax({
type: 'GET',
url: '@Url.Action("GetUnitDataRangeParamsVals", "UnitReportDataRangeParams")',
data: { unit: unitval, report: 1 },
contentType: 'application/json',
cache: false,
success: function(returneddata) {
populatedatarangeprams(1, returneddata);
},
error: function() {
alert('error - returneddata.error.stringify');
}
});
model = JSON.stringify({ unit: unitval, report: 2 });
$.ajax({
type: 'GET',
url: '@Url.Action("GetUnitDataRangeParamsVals", "UnitReportDataRangeParams")',
data: { unit: unitval, report: 2 },
contentType: 'application/json',
cache: false,
success: function(returneddata) {
populatedatarangeprams(2, returneddata);
},
error: function() {
alert('error - returneddata.error.stringify');
}
});
model = JSON.stringify({ unit: unitval, report: 3 });
$.ajax({
type: 'GET',
url: '@Url.Action("GetUnitDataRangeParamsVals", "UnitReportDataRangeParams")',
data: { unit: unitval, report: 3 },
contentType: 'application/json',
cache: false,
success: function(returneddata) {
populatedatarangeprams(3, returneddata);
},
error: function() {
alert('error - returneddata.error.stringify');
}
});
model = JSON.stringify({ unit: unitval, report: 4 });
$.ajax({
type: 'GET',
url: '@Url.Action("GetUnitDataRangeParamsVals", "UnitReportDataRangeParams")',
data: { unit: unitval, report: 4 },
contentType: 'application/json',
cache: false,
success: function(returneddata) {
populatedatarangeprams(4, returneddata);
},
error: function() {
alert('error - returneddata.error.stringify');
}
});
if (!checkboxSelected) {
return;
}
// from
rptval = $('[id^=ckbx_]').filter(':checked').val();
setEmailAndGenerateValsForUnitReportPair(unitval, rptval);
}); // $('#unitsselect').change(function ()
// Checkbox selection has changed; if Unit has been selected, populate the email and generate vals
$(".ckbx").change(function() {
if (!this.checked) {
checkboxSelected = false;
reinitializeRecipientsAndGenerateVals();
return;
}
checkboxSelected = true;
// this unchecks all other checkboxes (from
$('.ckbx').not(this).prop('checked', false);
reinitializeRecipientsAndGenerateVals();
// If no unit is selected, vals can not be set, so exit now
if (!unitSelected) {
return;
}
var unitval = $('#unitsselect').val();
var rptval = $(this).val();
setEmailAndGenerateValsForUnitReportPair(unitval, rptval);
}); // $(".ckbx").change(function ()
}); // "ready" function
function setEmailAndGenerateValsForUnitReportPair(unitval, rptval) {
var model = JSON.stringify({ unit: unitval, report: rptval });
$.ajax({
type: 'GET',
url: '@Url.Action("GetUnitReportPairEmailAddresses", "UnitReportPair")',
data: { unit: unitval, report: rptval },
contentType: 'application/json', //<= this is paired with stringify above; if comment out one, comment out both
cache: false,
success: function(returneddata) {
populateemails(returneddata);
},
error: function() {
alert(returneddata.error.stringify);
}
});
// The above AJAX call retrieved email addr vals; the next one is for the "Generate and Email Report" section of the page
$.ajax({
type: 'GET',
url: '@Url.Action("GetUnitReportPairGenerateVals", "UnitReportPairGenerateVals")',
data: { unit: unitval, report: rptval },
contentType: 'application/json',
cache: false,
success: function(returneddata) {
populategeneratevals(returneddata);
},
error: function() {
alert(returneddata.error.stringify);
}
});
}
//Adapted from Jakes's answer here:
function isCheckedById(id) {
var checked = $("input[id=" + id + "]:checked").length;
return (checked != 0);
}
function populateemails(trampdata) {
// first, clear them all
$("#email1").val('');
$("#email2").val('');
$("#email3").val('');
// Now set those for which there are values
if (trampdata.UnitReportPairEmailVals.length > 0) {
$("#email1").val(trampdata.UnitReportPairEmailVals[0]);
}
if (trampdata.UnitReportPairEmailVals.length > 1) {
$("#email2").val(trampdata.UnitReportPairEmailVals[1]);
}
if (trampdata.UnitReportPairEmailVals.length > 2) {
$("#email3").val(trampdata.UnitReportPairEmailVals[2]);
}
}
function populategeneratevals(generateddata) {
// first, clear them all, if they had been set to something else
$("#dayofmonthselect").val('1st');
$("#ordinalselect").val('First');
$("#dayofweekselect").val('Monday');
$("#weekormonthselect").val('Month');
// Now set those for which there are values
var domOrdinalified = ordinalify(generateddata.generatevals.DayOfMonth);
$("#dayofmonthselect").val(domOrdinalified);
$("#ordinalselect").val(generateddata.generatevals.PatternOrdinal);
$("#dayofweekselect").val(generateddata.generatevals.PatternDOW);
$("#weekormonthselect").val(generateddata.generatevals.PatternInterval);
// Now set the correct radio button
if ($("#dayofmonthselect").val() === 0) {
$("#groupRptGenerationAndSendingByDayOfMonth").prop("checked", true);
} else {
$("#groupRptGenerationAndSendingBasedOnAPattern").prop("checked", true);
}
}
function ordinalify(domint) {
if (domint === 1 || domint === 21 || domint === 31) {
return domint + 'st';
}
if (domint === 2 || domint === 22) {
return domint + 'nd';
}
if (domint === 3 || domint === 23) {
return domint + 'rd';
}
return domint + 'th';
}
function populatedatarangeprams(rptval, returneddata) {
if (rptval === 1) {
// Produce Usage
$("#produsagefrom").val(returneddata.datarangeparams.TimeUnitsFrom);
$("#produsageto").val(returneddata.datarangeparams.TimeUnitsTo);
} else if (rptval === 2) {
// Delivery Performance
$("#delperffrom").val(returneddata.datarangeparams.TimeUnitsFrom);
$("#delperfto").val(returneddata.datarangeparams.TimeUnitsTo);
} else if (rptval === 3) {
// Price Compliance
$("#pricecompliancefrom").val(returneddata.datarangeparams.TimeUnitsFrom);
$("#pricecomplianceto").val(returneddata.datarangeparams.TimeUnitsTo);
} else if (rptval === 4) {
// Fill Rate
$("#fillratefrom").val(returneddata.datarangeparams.TimeUnitsFrom);
$("#fillrateto").val(returneddata.datarangeparams.TimeUnitsTo);
}
// TODO: Add 5 if/when Contract vs Market is added
}
function reinitializeRecipientsAndGenerateVals() {
$("#email1").val('');
$("#email2").val('');
$("#email3").val('');
$("#dayofmonthselect").val('1st');
$("#ordinalselect").val('First');
$("#dayofweekselect").val('Monday');
$("#weekormonthselect").val('Month');
}
您可以使用函数参数 reinit
,稍后将其绑定到 reinitializeRecipientsAndGenerateVals
(您要重用的函数)。
var onChange = (function(reinit) {
unitSelected = true;
reinit();
...
}).bind(null, reinitializeRecipientsAndGenerateVals)
$('#unitsselect').change(onChange)
好的,我已经找到了:
foo(); // <- function call
function foo() { // <- function declaration
}
"Declare function before calling it!" 或 "Do not rely on hoisting!" 似乎是一种晦涩的表达方式。
您可以通过将函数声明移到顶部来修复它。
我需要重新初始化来自两个不同事件(一个 html select 变化和一个复选框变化)的一些 html 元素的状态,所以我创建了一个我放置的函数在 "ready" 函数之外执行此操作,并从两个事件中调用它。
但是,JSLint 标记了对它的调用:
$('#unitsselect').change(function() {
unitSelected = true;
reinitializeRecipientsAndGenerateVals();
. . .
...作为 "out of scope";具体来说,它告诉我,
'reinitializeRecipientsAndGenerateVals' is out of scope.
并指出该行是有问题的行。
reinitializeRecipientsAndGenerateVals()
确实在 change 事件处理程序之外,也在 "ready" 函数之外。我将它放在就绪函数中以查看是否是问题所在,但我仍然从 JSLint 那里收到警告。
我怎样才能重用这个函数,这样我就不必在两个更改事件处理程序中移动它?
注意:This 有一个 "used out of scope" 部分,但没有 "is out of scope"
根据 this,所有版本的 JSLint 都使用“{a} 在绑定上下文之外使用”
更新
即使我将函数右移 到 更改事件处理程序中,JSLint 也会以同样的方式抱怨。
UDPATE 2
对于 Travis,这是整个辣酱玉米饼馅:
$(document).ready(function() {
var unitSelected = false;
var checkboxSelected = false;
// When unit is selected, populate the data range value elements; if checkbox selected,
// also populate email recipients and generate vals (specific day or based on a pattern)
$('#unitsselect').change(function() {
unitSelected = true;
reinitializeRecipientsAndGenerateVals();
var unitval = $('#unitsselect').val();
// This is admittedly kludgy - copying the same ajax call multiple times, changing only
// the report number; but a forloop attempt failed because of the asynchronous nature of
// it all; for some reason, populatedatarangeprams() was called only once, and with a
// rptval of 5 (when it "should have been" 1..4 instead).
var model = JSON.stringify({ unit: unitval, report: 1 });
$.ajax({
type: 'GET',
url: '@Url.Action("GetUnitDataRangeParamsVals", "UnitReportDataRangeParams")',
data: { unit: unitval, report: 1 },
contentType: 'application/json',
cache: false,
success: function(returneddata) {
populatedatarangeprams(1, returneddata);
},
error: function() {
alert('error - returneddata.error.stringify');
}
});
model = JSON.stringify({ unit: unitval, report: 2 });
$.ajax({
type: 'GET',
url: '@Url.Action("GetUnitDataRangeParamsVals", "UnitReportDataRangeParams")',
data: { unit: unitval, report: 2 },
contentType: 'application/json',
cache: false,
success: function(returneddata) {
populatedatarangeprams(2, returneddata);
},
error: function() {
alert('error - returneddata.error.stringify');
}
});
model = JSON.stringify({ unit: unitval, report: 3 });
$.ajax({
type: 'GET',
url: '@Url.Action("GetUnitDataRangeParamsVals", "UnitReportDataRangeParams")',
data: { unit: unitval, report: 3 },
contentType: 'application/json',
cache: false,
success: function(returneddata) {
populatedatarangeprams(3, returneddata);
},
error: function() {
alert('error - returneddata.error.stringify');
}
});
model = JSON.stringify({ unit: unitval, report: 4 });
$.ajax({
type: 'GET',
url: '@Url.Action("GetUnitDataRangeParamsVals", "UnitReportDataRangeParams")',
data: { unit: unitval, report: 4 },
contentType: 'application/json',
cache: false,
success: function(returneddata) {
populatedatarangeprams(4, returneddata);
},
error: function() {
alert('error - returneddata.error.stringify');
}
});
if (!checkboxSelected) {
return;
}
// from
rptval = $('[id^=ckbx_]').filter(':checked').val();
setEmailAndGenerateValsForUnitReportPair(unitval, rptval);
}); // $('#unitsselect').change(function ()
// Checkbox selection has changed; if Unit has been selected, populate the email and generate vals
$(".ckbx").change(function() {
if (!this.checked) {
checkboxSelected = false;
reinitializeRecipientsAndGenerateVals();
return;
}
checkboxSelected = true;
// this unchecks all other checkboxes (from
$('.ckbx').not(this).prop('checked', false);
reinitializeRecipientsAndGenerateVals();
// If no unit is selected, vals can not be set, so exit now
if (!unitSelected) {
return;
}
var unitval = $('#unitsselect').val();
var rptval = $(this).val();
setEmailAndGenerateValsForUnitReportPair(unitval, rptval);
}); // $(".ckbx").change(function ()
}); // "ready" function
function setEmailAndGenerateValsForUnitReportPair(unitval, rptval) {
var model = JSON.stringify({ unit: unitval, report: rptval });
$.ajax({
type: 'GET',
url: '@Url.Action("GetUnitReportPairEmailAddresses", "UnitReportPair")',
data: { unit: unitval, report: rptval },
contentType: 'application/json', //<= this is paired with stringify above; if comment out one, comment out both
cache: false,
success: function(returneddata) {
populateemails(returneddata);
},
error: function() {
alert(returneddata.error.stringify);
}
});
// The above AJAX call retrieved email addr vals; the next one is for the "Generate and Email Report" section of the page
$.ajax({
type: 'GET',
url: '@Url.Action("GetUnitReportPairGenerateVals", "UnitReportPairGenerateVals")',
data: { unit: unitval, report: rptval },
contentType: 'application/json',
cache: false,
success: function(returneddata) {
populategeneratevals(returneddata);
},
error: function() {
alert(returneddata.error.stringify);
}
});
}
//Adapted from Jakes's answer here:
function isCheckedById(id) {
var checked = $("input[id=" + id + "]:checked").length;
return (checked != 0);
}
function populateemails(trampdata) {
// first, clear them all
$("#email1").val('');
$("#email2").val('');
$("#email3").val('');
// Now set those for which there are values
if (trampdata.UnitReportPairEmailVals.length > 0) {
$("#email1").val(trampdata.UnitReportPairEmailVals[0]);
}
if (trampdata.UnitReportPairEmailVals.length > 1) {
$("#email2").val(trampdata.UnitReportPairEmailVals[1]);
}
if (trampdata.UnitReportPairEmailVals.length > 2) {
$("#email3").val(trampdata.UnitReportPairEmailVals[2]);
}
}
function populategeneratevals(generateddata) {
// first, clear them all, if they had been set to something else
$("#dayofmonthselect").val('1st');
$("#ordinalselect").val('First');
$("#dayofweekselect").val('Monday');
$("#weekormonthselect").val('Month');
// Now set those for which there are values
var domOrdinalified = ordinalify(generateddata.generatevals.DayOfMonth);
$("#dayofmonthselect").val(domOrdinalified);
$("#ordinalselect").val(generateddata.generatevals.PatternOrdinal);
$("#dayofweekselect").val(generateddata.generatevals.PatternDOW);
$("#weekormonthselect").val(generateddata.generatevals.PatternInterval);
// Now set the correct radio button
if ($("#dayofmonthselect").val() === 0) {
$("#groupRptGenerationAndSendingByDayOfMonth").prop("checked", true);
} else {
$("#groupRptGenerationAndSendingBasedOnAPattern").prop("checked", true);
}
}
function ordinalify(domint) {
if (domint === 1 || domint === 21 || domint === 31) {
return domint + 'st';
}
if (domint === 2 || domint === 22) {
return domint + 'nd';
}
if (domint === 3 || domint === 23) {
return domint + 'rd';
}
return domint + 'th';
}
function populatedatarangeprams(rptval, returneddata) {
if (rptval === 1) {
// Produce Usage
$("#produsagefrom").val(returneddata.datarangeparams.TimeUnitsFrom);
$("#produsageto").val(returneddata.datarangeparams.TimeUnitsTo);
} else if (rptval === 2) {
// Delivery Performance
$("#delperffrom").val(returneddata.datarangeparams.TimeUnitsFrom);
$("#delperfto").val(returneddata.datarangeparams.TimeUnitsTo);
} else if (rptval === 3) {
// Price Compliance
$("#pricecompliancefrom").val(returneddata.datarangeparams.TimeUnitsFrom);
$("#pricecomplianceto").val(returneddata.datarangeparams.TimeUnitsTo);
} else if (rptval === 4) {
// Fill Rate
$("#fillratefrom").val(returneddata.datarangeparams.TimeUnitsFrom);
$("#fillrateto").val(returneddata.datarangeparams.TimeUnitsTo);
}
// TODO: Add 5 if/when Contract vs Market is added
}
function reinitializeRecipientsAndGenerateVals() {
$("#email1").val('');
$("#email2").val('');
$("#email3").val('');
$("#dayofmonthselect").val('1st');
$("#ordinalselect").val('First');
$("#dayofweekselect").val('Monday');
$("#weekormonthselect").val('Month');
}
您可以使用函数参数 reinit
,稍后将其绑定到 reinitializeRecipientsAndGenerateVals
(您要重用的函数)。
var onChange = (function(reinit) {
unitSelected = true;
reinit();
...
}).bind(null, reinitializeRecipientsAndGenerateVals)
$('#unitsselect').change(onChange)
好的,我已经找到了:
foo(); // <- function call
function foo() { // <- function declaration
}
"Declare function before calling it!" 或 "Do not rely on hoisting!" 似乎是一种晦涩的表达方式。
您可以通过将函数声明移到顶部来修复它。