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之前的方式(推荐)来解决。
时间: 2024-10-12 11:42:23