javaScript_函数详细
函数基础
定义
函数声明
- 执行代码之前会先读取函数声明,无先后区别
<script type="text/javascript">
sayHi();//hi
function sayHi(){
alert("hi");
}
</script>
函数表达式
-使用前必须赋值,有先后区别
<script type="text/javascript">
var sayHi=function(){
alert("hi");
};
sayHi();//hi
</script>
不推荐,最后一个参数始终被看成函数体
<script type="text/javascript">
var sum=new Function("num1","num2","return num1+num2");
console.log(sum(10,20));
</script>
匿名函数
-又名拉姆达函数(lambda)
-function关键字后面没有表示符
-匿名函数对象的name属性是空字符串
-匿名函数可以当值使用
函数当返回值
<script type="text/javascript">
function createComparisonFuncton(propertyName){
return function(object1,object2){
var value1=object1[propertyName];
var value2=object2[propertyName];
if(value1<value2){return -1;}
else if(value1>value2){return 1;}
else{return 0;}
};
}
</script>
参数
-多出的实参会忽略
<script type="text/javascript">
</script>
访问参数
-arguments属性以数组形式保存参数列表
<script type="text/javascript">
var test=function(){console.log(arguments[0])};
test(10,20);//10
</script>
闭包
-有权限访问另一函数作用域中的变量的函数
-常见方式,函数内部创建另外一个函数
<script type="text/javascript">
function createComparisonFuncton(propertyName){
return function(object1,object2){
var value1=object1[propertyName];
var value2=object2[propertyName];
if(value1<value2){return -1;}
else if(value1>value2){return 1;}
else{return 0;}
};
}
</script>
作用域链
-每个执行环境都有变量对象用于表示变量
-调用函数时,会创建运行期上下文的内部对象(execution context)
-execution context的作用域链[scope chain]初始化为指向当前运回函数的[scope chain]
-[scope chain]保存各个对象作用域指针列表
-[scope chain]的[[scope]]指向各变量对象(函数作用域)包括,活动对象,全局对象,父级对象
-活动对象包括函数内部的局部变量和函数参数
-虚拟属性,不能访问
-同一父作用域中的闭包拥有一个相同的[[scope]]属性
<script type="text/javascript">
var fun1;//fun0执行后,fun1作用域链中引用了fun0,fun0不会消亡
(function(){
fun1=function(){console.log("i am fun1");};
})();
fun1();
</script>
闭包与变量
-闭包保存的是整个变量对象而不是某个特殊的变量
no copy
<script type="text/javascript">
function createFunction(){
var result=new Array();
for(var i=0;i<10;++){
result[i]=function(){return i;};
}
return result;
}
var a=createFunction();
for(var i=0;i<10;i++){console.log(a[i]());}//10*10
</script>
has copy
<script type="text/javascript">
function createFunction(){
var result=new Array();
for(var i=0;i<10;++){
result[i]=function(num){return function(){return num;};}(i);
}
return result;
}
var a=createFunction();
for(var i=0;i<10;i++){console.log(a[i]());}//0,1,...,9
</script>
其他
递归
-函数通过名字调用自身的情况下构成
<script type="text/javascript">
function factorial(num){
if(num<=1){return 1;}
else{return num*factorial(num-1);}
}
var anotherFactorial=factorial;
factoral=null;
alert(anotherFactorial(4));//出错,factoral已消亡
</script>
递归函数的赋值
-arguments.callee
-指向正在执行的函数的指针
-严格模式不通过,可以使用命名函数表达式
非严格模式下
<script type="text/javascript">
function factorial(num){
if(num<=1){return 1;}
else{return num*arguments.callee(num-1);}
}
var anotherFactorial=factorial;
factoral=null;
alert(anotherFactorial(4));
</script>
严格模式下和非严格模式均正常
<script type="text/javascript">
var factorial=(function f(num){
if(num<=1){return 1;}
else{return num*f(num-1);}
});
</script>
this对象
-在全局函数中,this指向window
-函数当做某个对象的方法时候,this指向那个对象
window中
<script type="text/javascript">
var name="zzz";
console.log(name);//zzz
console.log(this.name);//zzz
</script>
当做某个对象的方法时候
<script type="text/javascript">
var o=new Object();
o.name="zzz";
o.getName=function(){console.log(this.name);};
o.getName();//zzz
</script>
内存泄漏
-闭包的作用域链中保存这一个HTML元素,那么就意味着该元素将无法销毁
只要匿名函数存在,element的引用数至少也说1,所沿用内存永远不被回收
<script type="text/javascript">
function handler(){
var element=document.getElementById("someElement");
element.onclick=function(){alert(element.id);};
}
</script>
解决
<script type="text/javascript">
function handler(){
var element=document.getElementById("someElement");
var id=element.id;
element.onclick=function(){alert(id);};
element=null;
}
</script>
模仿块级作用域
-javaScript没有块级概念
-不限制多次声明,对后续声明不初始化
<script type="text/javascript">
(function(){
for(var i=0;i<10;i++){
alert(i);
}
})();
alert(i);//导致错误
</script>
私有变量
-javaScript没有私有成员的概念
<script type="text/javascript">
function MyObject(){
//私有变量
var name='zzz';
//public特权方法
this.name="this_zzz";
this.getName=function(){alert(name);};//访问私有变量
this.getName=function(){alert(this.name);};//访问公有变量
}
</script>
静态私有变量
-所有实例共享
<script type="text/javascript">
(function(){
var age=10;
object=function(){};
object.prototype.getAge=function(){alert(age);};
})();
</script>
模块模式 单例
-只有一个实例的对象
<script type="text/javascript">
var singleton=function(){
//私有变量
var name="zzz";
var age=10;
//特权
return {work:doctor,getName:function(){alert(name);},gerAge(){alert(age);}};
};
</script>
增强模块模式
-适合某些单例必须说某种类型的实例
<script type="text/javascript">
var singleton=functon(){
//私有变量
var name="zzz";
var age=10;
//创建对象
var object=new CustomType();
//添加特权
object.getName=function(){console.log(name);};
//返回对象
return object;
};
</script>
涉及属性
name | 解析 | 数据类型 |
---|---|---|
arguments.callee | 指向正在执行的函数的指针 | 引用 |
arguments | 保存传入实参列表 | Arra |