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>
发布了53 篇原创文章 · 获赞 12 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/bingqise5193/article/details/100073370