在jQuery.getData中renderCallback使用不同创造方式的结果

在jQuery.getData中renderCallback使用不同创建方式的结果

JavaScript 中需要创建函数的话,有两种方法:函数声明、函数表达式,各自写法如下:
// 方法一:函数声明
function foo() {}
// 方法二:函数表达式
var foo = function () {};
另外还有一种自执行函数表达式,主要用于创建一个新的作用域,在此作用域内声明的变量不会和其它作用域内的变量冲突或混淆,大多是以匿名函数方式存在,且立即自动执行:

(function () {
// var x = ...
})();

 

此种自执行函数表达式归类于以上两种方法的第二种,也算是函数表达式。



当我使用jQuery.getData时,代码如下:

$.getData("getDeptUsers/",jsonParam,null,getDepUseFn,"0");
var getDepUseFn=function(ret){
var data=ret.data;
var empNum="共"+data.length+"人";
$("#deptEmpNum").val(empNum);
if(data.length>0){
...
}else{
...
}
...
}

此时控制台不报错,但getDepUseFn并不执行,js中加断点检查得知调用getDepUseFn时指向undefined;
尝试在作为参数引用时就调用$.getData("getDeptUsers/",jsonParam,null,getDepUseFn(),"0");则直接报错undefined;
再次尝试其他创建函数的方式:
function getDepUseFn(ret){};
之后函数被正常调用。



JavaScript 解释器中存在一种变量声明被提升(hoisting)的机制,也就是说变量(函数)的声明会被提升到作用域的最前面,即使写代码的时候是写在最后面,也还是会被提升至最前面。
因此推测在调用时,getDepUseFn已经被声明但未赋值,验证:

$.getData("getDeptUsers/",jsonParam,null,getDepUseFn,"0");
console.log(getDepUseFn); //Line76
var getDepUseFn=function(ret){
var data=ret.data;
var empNum="共"+data.length+"人";
$("#deptEmpNum").val(empNum);
if(data.length>0){
...
}else{
...
}
...
}
console.log(getDepUseFn); //Line99

 

测试结果:
getCompanyDept.js:76 undefined
getCompanyDept.js:99 $.on.getDepUseFn(ret)
结论:
1、猜测使用函数表达式方式创建getData的参数函数时,由于js的声明提前机制,导致调用了未赋值函数。
2、可用函数声明的方式回避这个问题,也可以用直接将函数创建在getData之前的方式(推荐)来解决。