Skip to content

Commit 200db46

Browse files
committed
update
1 parent e198627 commit 200db46

2 files changed

Lines changed: 188 additions & 140 deletions

File tree

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<title>js函数的call和apply方法</title>
7+
<style type="text/css">
8+
h1 {
9+
text-align: center;
10+
}
11+
12+
pre {
13+
font-size: 16px;
14+
}
15+
</style>
16+
</head>
17+
18+
<body>
19+
<h1>JS函数的call和apply与bind方法</h1>
20+
<hr />
21+
22+
<pre>
23+
在 JavaScript 中,call、apply 和 bind 是函数对象的三个内置方法,用于显式地设置函数执行时的 this 上下文。它们都属于 Function.prototype,因此所有函数都可以使用。
24+
25+
一、call、apply 和 bind的共同点
26+
1.都可以改变函数内部 this 的指向。
27+
2.第一个参数都是要绑定给 this 的对象(如果传入 null 或 undefined,在非严格模式下会默认指向全局对象,如浏览器中的 window)。
28+
29+
30+
二、call、apply 和 bind的区别
31+
<table border="1" cellpadding="10" cellspacing="0" style="margin: auto;">
32+
<tr><th>方法</th><th>是否立即执行</th><th>参数传递方式</th><th>返回值</th></tr>
33+
<tr><td>call</td><td>✅ 立即执行</td><td>逐个参数传递 func.call(thisArg, arg1, arg2, ...)</td><td>函数执行结果</td></tr>
34+
<tr><td>apply</td><td>✅ 立即执行</td><td>以数组形式传递参数 func.apply(thisArg, [arg1, arg2, ...])</td><td>函数执行结果</td></tr>
35+
<tr><td>bind</td><td>❌ 不立即执行</td><td>逐个参数传递(可预设)func.bind(thisArg, arg1, arg2, ...)</td><td>返回一个新函数</td></tr>
36+
</table>
37+
38+
三、call、apply 和 bind的语法与示例
39+
1. call
40+
语法:
41+
func.call(thisArg, arg1, arg2, ...)
42+
示例:
43+
function greet(greeting, punctuation) {
44+
console.log(`${greeting}, ${this.name}${punctuation}`);
45+
}
46+
const person = { name: 'Alice' };
47+
greet.call(person, 'Hello', '!'); // 输出: Hello, Alice!
48+
49+
50+
2. apply
51+
语法:
52+
func.apply(thisArg, [argsArray])
53+
示例:
54+
greet.apply(person, ['Hi', '?']); // 输出: Hi, Alice?
55+
56+
常用于将数组作为参数传给函数,例如:
57+
const numbers = [1, 2, 3, 4];
58+
const max = Math.max.apply(null, numbers); // 等价于 Math.max(1,2,3,4)
59+
60+
61+
3. bind
62+
语法:
63+
const newFunc = func.bind(thisArg, arg1, arg2, ...);
64+
特点:
65+
1.返回一个新函数,其 this 被永久绑定(即使再用 call/apply 也无法改变)。
66+
2.可用于预设部分参数(柯里化)。
67+
示例:
68+
const boundGreet = greet.bind(person, 'Hey');
69+
boundGreet('!'); // 输出: Hey, Alice!
70+
71+
典型用途:
72+
1.事件处理中绑定 this
73+
2.创建具有固定上下文的回调函数
74+
class Button {
75+
constructor(name) {
76+
this.name = name;
77+
}
78+
handleClick() {
79+
console.log(`Button ${this.name} clicked`);
80+
}
81+
}
82+
83+
const btn = new Button('Submit');
84+
document.getElementById('myBtn').addEventListener('click', btn.handleClick.bind(btn)); // 绑定 this,避免在事件回调中丢失
85+
86+
87+
四、总结口诀
88+
“Call 一个个,Apply 用数组,Bind 不执行只返回。”
89+
call 和 apply 立即调用,区别在于参数形式;
90+
bind 返回绑定后的新函数,常用于延迟执行或固定上下文。
91+
92+
每一个函数都包含两个非继承而来的方法:call、apply。这俩个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。
93+
94+
call、apply的用途之一就是传递参数,但事实上,它们真正强大的地方式能够扩充函数赖以运行的作用域。
95+
使用call()、aplly()来扩充作用域的最大好处就是对象不需要与方法有任何耦合关系。
96+
call方法简单的实现。
97+
98+
99+
</pre>
100+
</body>
101+
<script type="text/javascript" charset="UTF-8">
102+
103+
//call apply bind 的最简调用
104+
{
105+
// 任意一个函数都包含call和apply和bind方法
106+
function sum(x, y) {
107+
return x + y;
108+
}
109+
110+
// call的语法:function.call(thisArg, arg1, arg2, ...);
111+
var result1 = sum.call(null, 10, 20);//用call方法把sum函数绑定到this【Fn1】函数中(这俩个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。)
112+
console.log('call的调用:', result1);
113+
114+
115+
// apply的语法:function.apply(thisArg, [argsArray]);
116+
var result2 = sum.apply(null, [100, 200]); //apply方法和call方法差不多,把另一个方法绑定到当前方法中,【注:apply里面是 数组,这是它和 call方法的区别】
117+
console.log('apply的调用:', result2);
118+
119+
120+
// bind的语法:function.bind(thisArg, arg1, arg2, ...);
121+
var result3 = sum.bind(null, 30, 40); //bind方法创建一个新的函数,在调用时this值被绑定到传入的第一个参数上,后续参数作为预设参数传递给函数。
122+
console.log('bind的调用:', result3()); // 注:bind调用绑定后返回的是一个函数,需要加括号执行调用。
123+
}
124+
125+
//call apply 简单的用法:绑定一些函数或一个作用域中,用于传递参数和调用
126+
{
127+
// 任意一个函数都包含call和apply和bind方法
128+
function sum(x, y) {
129+
console.log('调用时的this指向:', this); // 查看this指向
130+
return x + y;
131+
}
132+
133+
function Fn1(num1, num2) {
134+
return sum.call(this, num1, num2);//用call方法把sum函数绑定到this【Fn1】函数中(这俩个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。)
135+
}
136+
137+
function Fn2(num1, num2) {
138+
this.add = 666; // 给this对象添加一个属性,用于验证this指向
139+
return function () {
140+
return sum.apply(this, [num1, num2]); //apply方法和call方法差不多,把另一个方法绑定到当前方法中,【注:apply里面是 数组,这是它和 call方法的区别】
141+
}(); // 这里使用一个立即调用的函数表达式来确保this指向正确
142+
}
143+
144+
function Fn3(num1, num2) {
145+
var boundSum = sum.bind(this, num1, num2); //bind方法创建一个新的函数,在调用时this值被绑定到传入的第一个参数上,后续参数作为预设参数传递给函数。
146+
return boundSum(); // 调用绑定后的函数
147+
}
148+
149+
console.log('\ncall的调用:', Fn1(10, 20));
150+
console.log('\napply的调用:', Fn2(50, 30));
151+
console.log('\nbind的调用:', Fn3(70, 80));
152+
}
153+
154+
//call apply 扩充函数的作用域:下如实现重载功能!
155+
{
156+
window.color = 'red';//创建一个全局变量
157+
var obj = { color: 'blue' }//创建一个对象
158+
159+
function mupiao() {
160+
alert(this.color); //mupiao函数在这里就只是把自己的color对应的值弹出来(使用call()、aplly()来扩充作用域的最大好处就是对象不需要与方法有任何耦合关系。)
161+
}
162+
163+
mupiao.call(window); //调用mupiao方法
164+
mupiao.call(obj);
165+
}
166+
167+
168+
//call apply 方法的【原理】简单模拟与实现
169+
{
170+
function test1(a, b) { //函数或方法(实现求和功能)
171+
return a + b;
172+
}
173+
174+
function Obj(x, y) { //自定义对象
175+
this.x = x; //属性等于它自己
176+
this.y = y;
177+
}
178+
179+
var o = new Obj(10, 20);//实例化自定义对象
180+
o.method = test1; //用o对象的method方法来接收test1方法【此时: o.method到相当于test1了!】
181+
alert('结果:' + o.method(o.x, o.y));
182+
delete o.method;//因为o.method是临时定义的,所以用完要删除掉!
183+
184+
//alert(test1.call(o , o.x , o.y));
185+
}
186+
</script>
187+
188+
</html>

‎Function函数/js函数的call和apply方法.html‎

Lines changed: 0 additions & 140 deletions
This file was deleted.

0 commit comments

Comments
 (0)