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>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值