js call/apply/bind 及 手寫源碼

call與apply與bind異同

  1. 作用:均爲改變this指向
  2. call/bind傳參爲多個參數,apply傳參爲一個參數數組
  3. bind的時候function函數不執行,需手動執行,call/apply的時候函數自動執行

例子

function Person(name, age) {
	this.name = name;
	this.age = age;
}
Person('doudou', 28); //執行時,Person內this指向window,執行完後,window.name 就等於doudou
var stu1 = new Person('feifei',29); //執行時,Person內this指向stu1,執行完後,stu1.name 等於feifei
var stu2 = {};
Person.call(stu2, 'fangfang', 27); //改變this指向,Person內this指向stu2,執行完後,stu2.name 等於fangfang
Person.apply(stu2, ['liaoliao', 27]);//改變this指向,Person內this指向stu2,執行完後,stu2.name 等於liaoliao
Person.bind(stu2, ['xiaoxiao', 26])();////改變this指向,Person內this指向stu2,執行完後,stu2.name 等於xiaoxiao

實戰

call和apply可以用來借用別人的函數來完成自己的功能

//別人寫好的函數
function Person(name, age) {
	this.name = name;
	this.age = age;
}

//借過來用
function Student(name, age, grade, score) {
	Person.call(this, name, age);
	this.grade = grade;
	this.score = score;
}
var stu = new Student('doudou', 28, 2, 99)

call與apply與bind的源碼實現

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>手寫apply/bind/call</title>
</head>
<body>
	<script>
		Function.prototype.myApply = function (obj, arr) {
			let context = obj || window;
			// 此處this指向調用者,Person,誰調用,指向誰,給obj增加Person函數,Person函數裏面的this,指向obj
			context.func = this;
			// 執行函數即可
			// 利用擴展運算符,將一個數組轉爲用逗號分隔的參數序列
			context.func(...arr);
			// 刪除函數
			delete context.func;
		}
		// 利用擴展運算符,函數剩餘參數轉爲一個數組
		Function.prototype.myCall = function (obj, ...arr) {
			let context = obj || window;
			context.func = this;
			// 利用擴展運算符,將一個數組轉爲用逗號分隔的參數序列
			context.func(...arr);
			delete context.func;
		}
		Function.prototype.myBind = function (obj, arr) {
			let context = obj || window;
			let self = this;
			// 將apply執行作爲函數內返回,要執行這個函數才執行
			return function() {
			   // 此中的this爲函數的執行環境
			   return self.apply(context, arr);
			}
		}
		function Person(name, age) {
			this.name = name;
			this.age = age;
		}
		let stu1 = {}, stu2 = {}, stu3 = {};
		Person.myApply(stu1, ['liaoliao', 1]);
		Person.myCall(stu2, 'feifei', 2);
		Person.myBind(stu3, ['xiongxiong', 3])();
		console.log(stu1);
		console.log(stu2);
		console.log(stu3);
	</script>
</body>
</html>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章