call,apply,bind区别?

本文详细解析了JavaScript中call、apply与bind方法的区别,重点介绍了它们如何改变函数内部的this指向。call与apply用于立即调用函数,区别在于参数传递方式;bind则返回一个新的函数,允许后续调用。

call,apply,bind主要作用都是改变this指向的,但使用上略有区别,说一下区别:
call和apply的主要区别是在传递参数上不同,call后面传递的参数是以逗号的形式分开的,apply传递的参数是数组形式【Apply是以A开头的,所以应该是跟Array(数组)形式的参数】
bind返回的是一个函数形式,如果要执行,则后面要再加一个小括号,例如:bind(obj,参数1,参数2,)(),bind只能以逗号分隔形式,不能是数组形式。

### JavaScript 中 `bind`、`call` 和 `apply` 的区别 #### 1. **功能上的共同点** 它们的主要作用是改变函数内部的 `this` 指向。 #### 2. **主要区别** - **`call`**: 调用函数的同时立即执行,并可以显式指定 `this` 值,支持多个单独参数。 ```javascript function greet(greeting, punctuation) { console.log(greeting + ', ' + this.name + punctuation); } const person = { name: "Alice" }; greet.call(person, "Hello", "!"); // 输出: Hello, Alice! ``` - **`apply`**: 类似于 `call`,但它接受一个参数数组而不是单个参数列表。 ```javascript function greet(greeting, punctuation) { console.log(greeting + ', ' + this.name + punctuation); } const person = { name: "Bob" }; greet.apply(person, ["Hi", "?"]); // 输出: Hi, Bob? ``` - **`bind`**: 返回一个新的函数,不会立即执行原函数。新的函数会永久绑定到指定的对象上,无论如何调用它。 ```javascript function greet(greeting, punctuation) { console.log(greeting + ', ' + this.name + punctuation); } const person = { name: "Charlie" }; const boundGreet = greet.bind(person, "Hey"); boundGreet(", ."); // 输出: Hey, Charlie. ``` --- ### 自定义实现 `bind` 方法 以下是基于引用中的逻辑实现的一个完整的 `bind` 方法: ```javascript Function.prototype.myBind = function (context, ...args) { if (typeof this !== "function") { throw new TypeError("What is trying to be bound is not callable"); } const fn = this; return function boundFn(...boundArgs) { // 判断是否通过 new 调用此函数 const isConstructorCall = this instanceof boundFn; const finalContext = isConstructorCall ? this : context || globalThis; return fn.apply(finalContext, args.concat(boundArgs)); }; }; ``` #### 实现细节明 1. 如果尝试绑定的内容不是一个函数,则抛出错误[^1]。 2. 使用闭包返回一个新的函数 (`boundFn`),该函数会在被调用时应用原始函数上下文和参数[^2]。 3. 当前函数如果作为构造器调用(即通过 `new`),则忽略传入的 `context` 并设置为新实例本身[^4]。 4. 合并初始绑定参数与后续调用时传递的参数,并使用 `apply` 执行目标函数[^3]。 --- ### 示例验证 ```javascript const user = { name: "John", }; function greeting(timeOfDay, activity) { console.log(`Good ${timeOfDay}, my name is ${this.name}. I like to ${activity}`); } // 使用自定义 bind const morningActivity = greeting.myBind(user, "morning"); morningActivity("run"); // Good morning, my name is John. I like to run. // 构造器场景测试 class MyClass {} MyClass.prototype.method = function () { console.log(this); }; const methodBound = MyClass.prototype.method.myBind({}); new methodBound(); // 正确输出实例对象而非绑定的上下文 ``` --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值