文章目录
前言
call apply bind,这三者都是用来改变函数的this对象的指向的。
通俗来讲就是,东风之礼,借来可用
一、使用上的异同
1. 相似之处:
都是用来改变函数的this对象的指向的。
第一个参数都是this要指向的对象。
都可以利用后续参数传参。
2. 不同之处
call 的传参是单个传参
apply 传参是以一个数组的行书
bind 非常特殊,可在对象后追加,也可以在传参数进行输入
二、call详细用法
1. 通俗解释
字面意思是“借用”,“请求”,一个场景:当你十分想抽烟,结果手里没带火机,也没有烟,这时候你需要去借烟和活(虽然是有点过分)
2. 代码案例
var smokeMe = {
name: "没有香烟",
tool: "没有火机",
smoking: function (a, b) {
alert("我在用" + this.tool + "点" + this.name + "==>" + a + b);
},
};
var smokerYou = {
name: "宇宙牌香烟",
tool: "石英火机",
};
smokeMe.smoking.call(smokerYou, "白嫖", "心里美滋滋");
3. Js手写call
首先context为可选参数,如果不传的话默认上下文是window
接下来给content创建一个fn属性,并将值设置为需要调用的函数
因为call可以传入多个参数作为调用函数的参数,所有需要将参数剥离出来
然后调用函数并将对象上的函数删除
Function.prototype.Mycall = function (val) {
val = val || window;
val.fn = this;
const args = [...arguments].slice(1);
const result = val.fn(...args);
delete val.fn;
return result;
};
smokeMe.smoking.Mycall(smokerYou, "白嫖", "心里美滋滋");
apply详细用法
1. 代码案例
使用方法与call一致,传入第二个参数的形式是数组
smokeMe.smoking.apply(smokerYou,["白嫖", "心里美滋滋"]);
2. Js手写apply
Function.prototype.myApply = function (context) {
if (typeof this !== "function") {
throw new TypeError("Error");
}
context = context || window;
context.fn = this;
let result;
if (arguments[1]) {
result = context.fn(...arguments[1]);
} else {
result = context.fn();
}
delete context.fn;
return result;
};
smokeMe.smoking.apply(smokerYou,["白嫖", "心里美滋滋"]);
bind详细用法
1. 代码案例
使用方法与call传参形式也可以,在后面传参也可以
smokeMe.smoking.bind(smokerYou,"白嫖", "心里美滋滋")();
smokeMe.smoking.bind(smokerYou)("白嫖", "心里美滋滋");
smokeMe.smoking.bind(smokerYou,["白嫖", "心里美滋滋"])();
smokeMe.smoking.bind(smokerYou)(["白嫖", "心里美滋滋"]);
2. Js手写bind
Function.prototype.myApply = function (context) {
if (typeof this !== "function") {
throw new TypeError("Error");
}
context = context || window;
context.fn = this;
let result;
if (arguments[1]) {
result = context.fn(...arguments[1]);
} else {
result = context.fn();
}
delete context.fn;
return result;
};
smokeMe.smoking.bind(smokerYou)("白嫖", "心里美滋滋");
综合Demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.box {
width: 800px;
height: 500px;
border: 1px solid #ccc;
margin: 20px auto;
}
.box-title {
text-align: center;
}
.showList {
height: 290px;
width: 90%;
margin: 10px auto;
border: 1px solid #ccc;
overflow: auto;
}
.counts {
position: relative;
}
.demo {
white-space: pre;
}
.main {
position: absolute;
right: 0%;
width: 520px;
height: 24px;
top: 10%;
border: 1px #ccc solid;
background-color: #cccccc;
}
.title {
position: absolute;
right: 3px;
top: 4px;
width: 520px;
height: 24px;
}
</style>
</head>
<body>
<div class="box">
<h1 class="box-title">call apply bind</h1>
<div style="margin-left: 45%">
<button onclick="setfun()">函数调用</button>
<button onclick="setCall()">call</button>
<button onclick="setApply()">apply</button>
<button onclick="setBind()">bind</button>
</div>
<div>
<div class="showList">
<div class="counts">
<div class="demo"></div>
<div class="main"></div>
<div class="title">显示结果区域:(<span class="idea"></span>)</div>
</div>
</div>
</div>
</div>
</body>
<script>
let showUl = document.querySelector(".counts");
let showMain = document.querySelector(".main");
let showDemo = document.querySelector(".demo");
let showIdea = document.querySelector(".idea");
var showText = "";
var obj1 = {
name: "猿人甲",
gender: "男",
age: 24,
watchThis: function (a, b) {
showText =
this.name +
" , " +
this.gender +
" ,今年" +
this.age +
",参数:" +
a +
b;
},
};
var obj2 = {
name: "媛人乙",
gender: "女",
age: 18,
};
showDemo.innerHTML = `
var obj1 = {
name: "猿人甲",
gender: "男",
age: 24,
watchThis: function (a, b) {
showText = this.name + " , " + this.gender + " ,今年" + this.age +"参数" +
a +
b; ;
},
};
var obj2 = {
name: "媛人乙",
gender: "女",
age: 18,
};`;
function setfun() {
obj1.watchThis();
showMain.innerHTML = "obj1.watchThis()====>" + showText;
showIdea.innerHTML = "直接调用函数,this指向的是上一级实例对象";
}
function setCall() {
obj1.watchThis.call(obj2, "单", "个");
showMain.innerHTML = "obj1.watchThis.call(obj2)====>" + showText;
showIdea.innerHTML = "call()方法将obj.watchThis方法this指向obj2";
}
function setApply() {
obj1.watchThis.apply(obj2, ["数", "组"]);
showMain.innerHTML = "obj1.watchThis.apply(obj2)====>" + showText;
showIdea.innerHTML = "apply()方法将obj.watchThis方法this指向obj2";
}
function setBind() {
// obj1.watchThis.bind(obj2)("单", "个");
obj1.watchThis.bind(obj2, "单", "个")();
showMain.innerHTML = "obj1.watchThis.bind(obj2)()====>" + showText;
showIdea.innerHTML = "bind()以方法将obj.watchThis方法this指向obj2";
}
</script>
</html>