函数的高级运用
一,函数的定义
1.函数的声明
function fn() {
console.log('我是函数声明');
}
2.函数的表达式
var fn_1 = function () {
console.log('我是表达式');
}
3.构造函数
var fn_2 = new Function('a', 'b', 'return a+b');
二,函数的调用
1.直接调用 函数名()
fn()
fn_1()
console.log(fn_2(1, 2));//3
2.自调用
(function (a) {
console.log(a);//1
console.log('我是匿名函数');//我是匿名函数
})(1);
var fn_1 = function () {
console.log('我是表达式');//我是表达式
}();
(function fn() {
console.log('我是函数声明');//我是函数声明
})()
3.call() apply()调用
fn.call()
fn_1.apply()
4.函数在对象中的调用
var obj = {
name: 'obj',
getName: function () {
console.log(name);//空
console.log(this.name);//obj
}
}
obj.getName()
5.函数在数组的调用
var arr = [1, 'a', { name: 'arr' }, function () { console.log(this); }, null, undefined, true, Set, Map, Symbol, [1, 2, 3]]
console.log(arr);//Array(11)
console.log(arr[3]);//ƒ () { console.log(this);
arr[3]()
6.函数作为参数
function fun(fn) {
console.log(fn);//ƒ () { console.log('我是函数也是参数'); }
fn()
}
fun(function () { console.log('我是函数也是参数'); })
7.函数作为返回值
function fun_1(n) {
return n
}
var n = fun_1(1)
var n = fun_1(true)
var n = fun_1(function () { console.log('我是函数也是返回值'); })//ƒ () { console.log('我是函数也是返回值'); }
console.log(n);//ƒ () { console.log('我是函数也是返回值'); }
n()
console.log(n());//undefined
三,闭包:定义在函数内部的一个函数
1.闭包的作用:
(1):可以访问父函数的变量
(2):可以锁住父函数的变量
2.闭包的本质:父函数作用域成为永恒作用域
function parent() {
var name = 'parent'
function child() {
console.log(name);//parent
}
child()
}
parent()
3.闭包的考点
闭包 this的指向 作用域的查找规则 预解析
var name = 'window'
var object = {
name: 'object',
getName: function () {
// console.log(name);
var name = 'getName'
console.log(name); // getName
console.log(this.name); // object
// function fn() {
// console.log(name); //
// console.log(this.name); //
// }
// fn()
// function name() {
// console.log(name); // f()
// console.log(this.name); //window
// }
// name()
// var name = function () {
// console.log(name); // f()
// console.log(this.name); // window
// }
// name()
return function () {
console.log(name); // getName
console.log(this.name); // window
}
console.log(name); // getName
}
}
// console.log(object.getName());
object.getName()()
// object.getName.call()
4.锁住父函数中的变量
<body>
<button id="btn">点赞(0)</button>
</body>
// 闭包
function random(min, max) {
var num = Math.floor(Math.random() * (max - min) + min)
return function () {
console.log(num);
}
}
var result = random(1, 10)
console.log(result);
result()
result()
result()
result()
result()
result()
result()
//获取
var btn =document.getElementById("btn")
//事件就相当于调用函数
btn.onclick=function(){
var count=0;
return function(){
count++;
btn.innerHTML=`点赞(${count})`;
}
}()
四,递归函数
(1) 递归:函数自己调用自己
(2) 特点:类似于循环
(3) 注意:必须有结束语句 (死循环)
//累加器
function getNum(n) {
if (n == 1) {
return 1
} else {
return n + getNum(n - 1)
}
}
console.log(getNum(100));
var obj = {
name: 'obj',
age: 18,
object: {
name: 'object',
age: { age: 18 }
},
arr: [1, 2, 3]
}
var newObj = {}
// 递归函数
function recursion(newObj, obj) {
for (key in obj) {
// 判断对象
if (obj[key] instanceof Object) {
// 进行递归深拷贝
newObj[key] = {}
recursion(newObj[key], obj[key])
// 判断数组
} else if (obj[key] instanceof Array) {
newObj[key] = []
recursion(newObj[key], obj[key])
} else {
newObj[key] = obj[key]
}
}
}
recursion(newObj, obj)
newObj.name = 'newObj'
newObj.object.name = 'newObj1'
newObj.object.age.age = 20
console.log(obj);
console.log(newObj);