定义函数的方法两种
- 函数声明
function fnName(arg0, arg1, arg2) {
//函数体
}
重要特征:函数声明提升
- 函数表达式
let fnName = function(arg0, arg1, arg2) {
//函数体
}
即创建一个匿名函数(因为function关键字后面没有标识符)赋值给变量fnName
使用前必须先赋值
7.1递归
递归函数是一个函数通过名字调用自身的情况下构成的
function fn(num) {
if (num <= 1) {
return 1;
} else {
return num * fn(num - 1);
}
}
但是在某些情况下会出错,如
let fn1=fn
fn=null
fn1(3)
使用arguments.callee(是一个指向正在执行的函数的指针,因此可以实现对函数的递归调用)
function fn(num) {
if (num <= 1) {
return 1;
} else {
return num * arguments.callee(num - 1);
}
}
但在严格模式下无法访问arguments.callee,可以使用命名函数表达式达成相同的效果
let fn1 = function f(num) {
if (num <= 1) {
return 1;
} else {
return num * f(num - 1);
}
}
7.2闭包
闭包概念:有权访问另一个函数作用域中的变量的函数
function fn(property) {
return function(obj1, obj2) {
let val1 = obj1[property];
let val2 = obj2[property];
// 做其他操作
};
}
执行环境、作用域、作用域链
function compare(val1, val2) {
if (val1 < val2) {
return -1;
} else {
return 1;
}
}
let result = compare(5, 10);
7.2.1闭包和变量
副作用:闭包只能取得包含函数中任何变量的最后一个值
可以通过创建另一个匿名函数强制让闭包的行为符合预期
7.2.2关于this对象
匿名函数的执行环境具有全局性,此this对象通常指向window
可以用let that=this重指向解决
7.2.3内存泄漏
闭包作用域链保存HTML元素,则该元素无法被销毁
在使用后重新赋值null解除引用,减少其引用数,确保正常回收其占用的内存
7.3模仿块级(私有)作用域
(function(){
// 块级作用域
})
7.4私有变量
任何在函数中定义的变量,都可以认为是私有变量
有权访问私有变量和私有函数的公有方法成为特权方法
创建特权方法的方式:
- 在构造函数中定义特权方法,有构造模式的缺点
function MyObj() {
let val = 10;
function fn() {
return false;
}
this.publicMethod = function() {
val++;
return fn();
};
}
- 在私有作用域中定义特权方法
7.5小结
原文地址:https://www.cnblogs.com/Mijiujs/p/12080364.html