• JavaScript函数高级应用


    函数

    在JS当中函数就是一个方法(一个功能体),基于函数一般都是为了实现某个功能
    函数诞生的目的就是为了实现封装:把实现一个功能的代码封装到一个函数中,后期想要实现这个功能,只需要把函数执行即可,不需要再次编写重复的代码,起到了低耦合,高内聚的作用

    函数的声明

    ES3标准
    function fn(){
    	//函数体:实现功能的代码
    }
    ES6标准
    let 函数名(变量名)=([参数])=>{
    	函数体
    }
    // 赋值给变量
    var box = function(num1,num2){
    return num1+num2;
    };
    // 用构造函数
    var fn = new Function('num1','num2','return num1+num2');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    函数作为引用数据类型中的一种,它也是按照引用地址来操作的,接下来我们学习一下函数的运作机制

    1.函数也是引用类型,首先会开辟一个新的堆内存,把函数体中的代码当做字符串存储到内存中(对象向内存中存储的是键值对)
    2.把开辟的堆内存地址赋值给函数名
    
    • 1
    • 2

    [函数执行]
    目的:把之前存储到对内存中的代码字符串变为真正的JS代码自上而下执行,从而实现应用的功能

    1. 函数执行,首先会形成一个私有的作用域(一个代码执行的环境,也是一个栈内存)
    2. 把之前在堆内存中存储的字符串复制一份过来,变为真正的JS代码
    
    • 1
    • 2

    函数中的参数

    参数是函数的入口:当我们在函数中封装一个功能 ,发现一些材料不确定,需要执行函数的时候用户传递进来才可以,此时我们就基于参数的机制,提供入口即可

    //此处的参数为形参:入口,形参是变量
    function sum(n,m){
    	var total = 0;
    	total = n + m;
    	console.log(total);
    }
    //此处函数执行传递的值是实参,实参是具体的数据值
    sum(10)//n=10,m=undefined
    sum();//n=undefined,m=undefined
    sum(10,20,30)//n=10,m=20,30没有形参变量接收
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    return返回值

    函数可以通过 return 语句返回一个值,当函数遇到一个return就会停止运行并返回一个值

    function box(){
    return '返回一个值';
    }
    alert(box());
    function pre(name,age){
    return name+age;
    }
    alert(pre('ary',10));
    var result=pre('ary',19);// 可以把函数返回的值赋给一个变量
    alert(result);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    作为值的函数

    把函数结果作为参数

    function box(sum,num){
    	return sum+num;
    }
    function sum(num){
    	return num + 10;
    }
    var result = box(sum(10),10);// 输出30
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    把函数本身当做参数

    function box(sum,num){
    	return sum(10)+num;
    }
    function sum(num){
    	return num+10;
    }
    var result = box(sum,10);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    arguments:函数内置的实参集合(不管你是否设置了形参,也不管你是否传递了实参)

    是一个类数组对象,不能用数组中的方法,即使设置形参变量,形参该是什么值还是什么值,但是ARG使用存储的是所欲传递进来的实参,所以它被称为实参集合。
    arguments有一个length属性,可以用它获取实参的个数

    function sum(){
    var total=0;
    for(var i=0;i<arguments.length;i++){
    	var item=arguments[i];
    	item=Number(item);
    	isNaN(item)?null:total+=item;
    }
    return total;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    arguments.callee

    存储的是函数名

    function sum(num){
    	if(num<=1){
    		return 1;
    	}else{
    		return num*arguments.callee(num-1);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    length

    传入参数的个数

    prototype

    apply()

    function sum(num1,num2){
    	return num1+num2;
    }
    function box(num1,num2){
    	return sum.apply(this,[10,10]);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    call()

    function sum(num1,num2){
    	return num1+num2;
    }
    function box(num1,num2){
    	return sum.call(this,10,10);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    匿名函数与具名函数

    // 把匿名函数赋值给变量
    var fn=function (){
    };
    oBox.onclick=function (){
    };
    // 通过自我执行来调用匿名函数
    (function (){
    	return 'Lee';
    })();
    // 把函数返回值赋值给变量
    var fn = (function (){
    	return 'Lee';
    })();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    自我执行匿名函数的传参

    var fn = (function (age){
    	return age;
    })(100);
    
    • 1
    • 2
    • 3

    闭包

    函数里放一个匿名函数
    闭包是指有权访问另一个函数作用域里的变量的函数
    闭包可以把局部变量驻留在内存中,避免使用全局变量

    function box(){
    	return function (){
    		return 'Lee';
    	}
    }
    alert(box()());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    闭包返回局部变量

    function box(){
    	var age = 100;
    	return function (){
    		return age;
    	};
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    使用全局变量进行累加

    var age = 100;
    function sum(){
    	age++;
    }
    sum();
    alert(age);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    使用局部变量进行累加

    function box(){
    	var age = 100;
    	age++;					//每次执行时都会初始化
    }	
    box();
    alert(age);				
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    使用闭包实现局部变量进行累加

    function box(){
    	var age = 100;
    	return function (){
    		age++;
    		return age;
    	};
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    闭包在数组中的应用

    function box(){
    	var arr = [];
    	for(var i=0;i<5;i++){
    		arr[i] = (function (num){
    			return function (){
    				return num
    			}
    		})(i);
    	}
    	return arr;
    }
    var b = box();
    alert(b[i]());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    闭包在运行时指向全局

    var user = 'the window';
    var box={
    	user : ' the box',
    	getUser : function (){
    		return function (){
    			return this.user;
    		}
    	}
    };
    alert(box.getUser()());// 输出'the window'
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    用对象冒充的方法改变 this 指向

    var user = 'the window';
    var box={
    	user : ' the box',
    	getUser : function (){
    		return function (){
    			return this.user;
    		}
    	}
    };
    alert(box.getUser().call(box));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在作用域链上改变指针指向

    var user = 'the window';
    var box={
    	user : ' the box',
    	getUser : function (){
    	// this 指向 box
    	var that = this;
    		return function (){
    		// this 指向 全局
    			return that.user;
    		}
    	}
    };
    alert(box.getUser()());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    模仿块级作用域

    Javascript 不会提醒你是否多次声明同一变量,如果再次声明同一变量它会视而不见。
    包含自我执行的匿名函数,可以实现私有作用域

    function box(){
    	(function (){
    		for(var i=0;i<5;i++){
    			alert(i);
    		}
    	})();
    
    // 这里可以继续使用 i 变量和上面的 i 变量没有关系
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    私有变量

    function Box(value){
    	var user = value;
    	function run(){
    		return '运行中';
    	}
    	this.publicGo = function (){
    		return user+run();
    	}
    	this.getUser = function (){
    		return user;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    实现接口方法共享

    (function (){
    	var user = '';
    	Box.prototype.getUser = function (){
    		return user;
    	};
    	Box.prototype.setUser = function (value){
    		user = value;
    	};
    })();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    单例对象是永远只实例化一次

    var box = function (){
    	var user = 'Lee';
    	function run(){
    		return '运行中';
    	}
    	var obj = {
    		publicGo : function (){
    			return user + run();
    		}
    	};
    	return obj;
    
    }();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    增强型

    function Desk(){}
    var box = function (){
    	var user = 'Lee';			// 私有变量
    	function run(){
    		return '运行中';			// 私有函数
    	}
    	var desk = new Desk();
    	desk.publicGo = function (){
    			return user + run();
    	};
    	return desk;
    }();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    Spring基础(3):复习
    跑通一个十年年前的细分着色器示例
    vue2+webpack升级vue3+vite,修改插件兼容性bug
    vue中v-for循环数组使用方法中splice删除数组元素(每次都删掉点击的下面的一项)
    Modern C++
    Spring Data的Repositories----Query by Example
    作为一个程序员,如何高效的管理时间?
    MySQL基础篇【第二篇】| 简单的查询、条件查询、排序查询
    AWS创建实例 启用/禁用 自动分配公有 IP
    5李欣频文案精华版
  • 原文地址:https://blog.csdn.net/qq_40850839/article/details/107575034