JavaScript学习12-函数进阶

本文详细探讨了JavaScript中的函数定义与调用方式,包括函数声明、匿名函数和newFunction。重点讲解了this的指向及其在不同调用场景下的变化,并介绍了改变this指向的call、apply和bind方法。此外,还阐述了严格模式的特点和应用场景,以及高阶函数、闭包、递归和浅拷贝与深拷贝的概念和用法。通过对这些核心概念的解析,帮助读者深入理解JavaScript的高级特性。
摘要由CSDN通过智能技术生成

函数定义和调用

函数定义的方式

1、函数声明:function关键字;

function 函数名(){}

2、函数表达式(匿名函数);

var 函数名=function(){}

3、new Function();

new Function('参数1','参数2','函数体')    //参数必须是字符串形式
var fn=new Function('a','b','console.log(a+b)');
fn();

所有函数都是Function的实例,函数也属于对象,所以函数也有原型对象,实例化函数对象也有对象原型。

函数调用的方式

1、普通函数
2、对象的方法
3、构造函数
4、绑定事件函数
5、定时器函数
6、立即执行函数

this

函数内的this指向

调用方式this指向
普通函数window
构造函数实例化对象
对象方法调用方法的对象
事件绑定绑定事件的对象
定时器函数window
立即执行函数window

改变函数内this指向的三种方式

call()
<script>
	var obj={
		name='andy'
	}
	function fn(a,b){
		console.log(this);
	}
	fn.call(obj,1,2);    //this指向对象obj
</script>
apply()
函数名.apply(thisArg,[argsArray])
// 调用一个函数,改变this指向,返回值是函数的返回值,传递的值必须包含在数组里
<script>
	var obj={
		name='andy'
	}
	function fn(a,b){
		console.log(this);
	}
	fn.apply(obj,[1,2]);    //this指向对象obj
</script>

应用:apply的参数必须是数组(伪数组),可以用来求一组数的最大值,比如Math.max(数1,数2,数3…)

<script>
	var arr=[1,3,23,22,12];
	var max=Math.max.apply(Math,arr);    //还是指向Math
</script>
bind()
函数名.bind(thisArg,arg1,arg2...)
// 不会调用函数,返回指定的this值和初始化参数改造的原函数拷贝
<script>
		var obj={
				name:'xiaoming'
			}
			function fn(){
				console.log(this)    //obj对象
			}
			var f=fn.bind(obj);
			console.log(f());    //undefined,函数没有返回值
</script>

严格模式

IE10以上支持,可以应用到在整个脚本或者个别函数中。
在所有语句前放一个特殊语句/在函数体内所有语句前

"use strict";
或者
'use strict';

严格模式和正常模式的script脚本不利于合并,可以将整个脚本文件放在一个立即执行函数中

<script>
	(function(){
		"use strict";
		...
	})()
</script>
严格模式下的一些变化

全局变量必须显式声明,不允许不声明就赋值。
不能使用delete删除变量。
构造函数不加new调用,this会报错。
全局作用域的this指向undefined。
对象不允许有重名的属性,函数不允许有重名的参数。
函数声明必须在顶层,不允许在非函数的代码块内声明函数。

高阶函数

对其他函数操作的函数,可以将函数作为参数,或返回一个函数。

<script>
	function fn(a,b,callback){
		console.log(a+b);
		callback&&callback();
	}
	fn(1,2,function(){
		console.log('函数作为参数');
	})
</script>
<script>
	function fn(){
		return function(){}
	}
</script>

闭包

变量作用域

函数内部可以使用全局变量,函数外部不可以使用局部变量,函数执行完毕局部变量会被销毁。

闭包closure

指有权访问另一个函数作用域中变量的函数
闭包主要作用:延伸变量作用范围

<script>
	function fun(){
			var a=10;
			function fn(){
				console.log(a);   //函数fn访问了另一个函数的局部变量a
			}
			fn();
		}
	fun();   //在这里设断点,观察到闭包是fun()
	//控制台》》源代码》》一直点击下一步》》作用域中出现“关闭”,就是闭包
	//console>>source>>下一步>>scope里出现closure,就是闭包
</script>

被访问的变量所在的函数就是闭包函数
利用闭包得到li的索引

<script>
	for(var i=0;i<lis.length;i++){
		(function(i){
			lis[i].onclick=function(){
				console.log(i);
			}
		})(i);
	}
</script>

递归

自己调用自己的函数

<script>
	function fn(){
		if(num==6){
			return;   //终止递归条件
		}
		num++;
		fn();
	}
	fn();
</script>

求1~n的阶乘

<script>
	function fn(m){
		if(m==1){
			return 1;
		}
		return m*fn(m-1);
	}
</script>

斐波那契数列

<script>
	function fn(n){
		if(n==1 || n==2){
			return 1;
		}
		return fn(n-1)+fn(n-2);
	}
</script>

浅拷贝和深拷贝

浅拷贝只复制地址,拷贝对象和原对象指向同一个地址,修改拷贝对象会影响原对象。

<script>
			var obj={
				id:1,
				name:'andy',
				msg:{
					age:18
				}
			}
			var o={}
			for(var k in obj){
				o[k]=obj[k];
			}
			console.log(o);    //age:20
			o.msg.age=20;
			console.log(o);    //age:20
			console.log(obj);    //age:20
			//这里是把对象obj的地址直接赋值给o对象,所以更改o的属性值会修改obj
</script>

ES6新增方法实现浅拷贝:Object.assign(拷贝对象,原对象)
深拷贝会创建一个新地址存放拷贝对象,修改拷贝对象不会影响原对象。

<script>
	function deepCopy(newobj,oldobj){
		for(var k in oldobj){
			var item=oldobj[k];
			if(item instanceof Array){
				newobj[k]=[];
				deepCopy(newobj[k],item);
			}else if(item instanceof Object){
				newobj[k]={};
				deepCopy(newobj[k],item)
			}else{
				newobj[k]=item;
			}
		}
	}
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值