JS高階三

Rayshaan發表於2020-12-03

2020.12.2

js高階==>this指向、call/apply/bind、變數儲存、淺/深拷貝、高階函式、閉包、閉包的應用

01.this指向

事件函式中:指向事件源
普通函式中:指向的是window物件
建構函式中:指向的是例項物件
普通物件中:指向的是當前物件

事件函式中

<body>
	<button id="btn">按鈕</button>
	<script>
		btn.onclick=function(){
			console.log(this);//指向btn
		}
	</script>
</body>

普通函式中

function add(){
	console.log(this);//指向window
}
add();

建構函式中

function Product(){
	this.buy=function(){
		console.log(this);//指向Product
	}
}
var p=new Product();
p.buy();

普通物件中

var stu={
	name:'zs',
	eat:function(){
		console.log(this);//指向stu
	}
}
stu.eat();

02.call、apply、bind

call apply和bind都可以用來修改this指向。只是使用方式不一樣

var stu={
	name:'zs',
	age:12,
	weight:200
}
function add(a,b){
	console.log(a,b,this.age);
}
//fn.call(所要指向的物件,引數1,引數2,...) 呼叫fn函式並修改this指向
add.call(stu,1,2);

// fn.apply(所要指向的物件,[引數1,引數2,...]) 呼叫fn函式並修改this指向
add.apply(stu,[1,2]);

//bind不會直接呼叫函式,而會返回一個新的函式,返回的新函式修改了this指向
var fn=add.bind(stu,1,2);
fn();

03.變數在記憶體中的儲存

基本資料型別:在記憶體中以值的形式存在。 字串、數值、布林型別、null、undefined
複合資料型別:在記憶體中以地址的形式存在。 物件

var a=10;
var b=a;
a=100;
//a只會把值賦給b,修改a不影響b的值
console.log(b);//輸出10
var stu={
	name:'zs'
}
var stu1=stu;
stu.name='ls';
//stu的地址賦給stu1,stu和stu1的地址都指向同一個資料,修改任意一個全部資料都會改變
console.log(stu1.name);//輸出ls

在這裡插入圖片描述

04.淺拷貝

淺拷貝:直接把物件的屬性一一賦值,不考慮屬性值型別

var stu={
	name:'zs',
	age:14,
	hobby:['唱歌','跳舞'],
	score:{
		math:89,
		english:100
	}
}
//淺拷貝
var stu1={};
stu1.name=stu.name;
stu1.age=stu.age;
stu1.hobby=stu.hobby;
stu1.score=stu.score;
//淺拷貝後,如果屬性值為物件的時候,只要修改一個,其餘物件對應資料都會改變
stu.hobby[0]="彈吉他";//stu和stu1的hobby:["彈吉他",'跳舞']

//快速實現淺拷貝
var stu2={};
for(var i in stu){
	stu2[i]=stu[i];
}

05.深拷貝

深拷貝:如果物件的屬性值為基本資料型別,直接拷貝。如果物件屬性對應的值物件,需要解析物件,再去拷貝

var stu={
	name:'zs',
	age:14,
	hobby:['唱歌','跳舞'],
	score:{
		math:89,
		english:100,
		lizong:[100,100,200]
	}
}
//深拷貝
var stu1={}
stu1.name=stu.name;
stu1.age=stu.age;
stu1.hobby=[];
stu1.hobby[0]=stu.hobby[0];
stu1.hobby[1]=stu.hobby[1];
stu1.score={};
stu1.score.math=stu.score.math;
stu1.score.english=stu.score.english;

// 快速實現深拷貝(函式遞迴呼叫)
function deepCopy(){

}

06.高階函式

函式作為函式的實參

function add(time,color){
	setTimeout(function(){
		color();
	},time);
}
add(1000,function(){
	txt.style.color='red';
});

07.閉包

閉包:函式巢狀
功能(2種作用獨立):
1.擴大了變數的作用域
2.縮小變數的作用域,防止變數汙染

//擴大了變數的作用域
function fn(){
	//函式add就是閉包
	// 正常情況下 add的作用範圍是fn內部
	//通過return將add的作用範圍擴大到fn外,即可在外面操作add內的變數
	return function add(x,y){
		console.log(x+y);
	}
}
var fn1=fn();
fn1(1,2);//3


//縮小變數的作用域,防止變數汙染
(function(){
	//放置的是一段有特殊功能的程式碼
	var m=10;
})();
// 自呼叫函式 ;( function(){})(); 前後都需要有;
console.log(m);//10

08.閉包應用

1.遍歷新增事件

<body>
	<button>按鈕</button>
	<button>按鈕</button>
	<button>按鈕</button>
	<button>按鈕</button>
	<button>按鈕</button>
	<button>按鈕</button>

	<script>
		var btns=document.getElementsByTagName('button');
		for(var i=0;i<btns.length;i++){
			/*btns[i].οnclick=function(){
				// i是全域性變數,點選的時候i的值已經是btns.length;
				btn[i].style.background='lime';
			}*/
			//通過閉包改進(縮小了i的作用域)
			(function(i){
				btns[i].onclick=function(){
					btns[i].style.background='lime';
				}
			})(i);
		}
	</script>

2.計時器

//計數器
// 1、可以在函式的外部訪問到函式內部的區域性變數
// 2、讓這些變數始終儲存在記憶體中,不會隨著函式的結束而自動銷燬
var add=(function(){
	var count=0;
	return function(){
		return count+=1;
	}
})();
console.log(add());//1
console.log(add());//2
console.log(add());//3
console.log(add());//4

相關文章