(一)call
call 的基本用法
function person () {
console.log(this.name)
}
let me = {
name: 'zfb'
}
person.call(me) // zfb
person.call(me) 的意思是,调用 person 这个函数,并且把 person 函数中的 this 指向 me 这个对象,call 传参数是一个一个传
function person (a, b) {
console.log(this.name)
console.log(a)
console.log(b)
}
let me = {
name: 'zfb'
}
person.call(me, 1, 2)
// zfb
// 1
// 2
call 的作用是修改 this 指向,上面 this 指向了me这个对象
(二)apply
apply 与 call 不同的是。apply 接受的参数是一个数组,即使是一个参数,也需要放进数组里面
接收的时候,一个一个接收
function person (a, b) {
console.log(this.name)
console.log(a)
console.log(b)
}
let me = {
name: 'zfb'
}
person.apply(me, [1, 2])
// zfb
// 1
// 2
(三)特殊情况
如果给call 、apply 传入的第一个参数是 undefined 或者 null,则this指向window
function person (a, b) {
console.log(this)
console.log(a)
console.log(b)
}
let me = {
name: 'zfb'
}
person.apply(undefined, [1, 2])
person.call(undefined, 1, 2)
person.apply(null, [1, 2])
person.call(null, 1, 2)
输出:
(四)bind
bind 作用也是改变this指向,但是与call、apply不同的是,call、apply 绑定之后会立即执行,但是bind 不会立即执行,需要再次调用
function person (a, b) {
console.log(this)
console.log(a)
console.log(b)
}
let me = {
name: 'zfb'
}
person.bind(me, 1, 2) // 这时候控制台什么都没发生
person.bind(me, 1 ,2)() // 手动调用
// {name: "zfb"}
// 1
// 4
也就是说,bind返回一个新的函数,然后我们需要去调用新的函数
const newFunction = person.bind(me, 1, 2) // 这时候控制台什么都没发生
console.log(newFunction)
// ƒ person (a, b) {
// console.log(this)
// console.log(a)
// console.log(b)
// }
newFunction() // 调用新返回的函数
// {name: "zfb"}
// 1
// 4
所以传参数,可以把参数传给新的返回的函数
person.bind(me)(1, 2)
// {name: "zfb"}
// 1
// 4
如果绑定 null 或者 undefined,同样this 指向window
person.bind(null)(1, 2)
person.bind(undefined)(1, 2)
(五)手写 call 方法
fn.call(obj) 的本质就是 obj.fn()
let me = {
name: 'zfb',
person: function (a, b) {
console.log(this)
console.log(a)
console.log(b)
}
}
me.person(1, 2)
所以我们要做的就是,把绑定的函数挂载到传入的this指向的对象上
Function.prototype.call = function (obj, ...args) {
// 如果第一个参数是 null 或者 undefined 赋值为 window
if (obj === null || obj === undefined) {
obj = window
}
// 谁调用call,this就指向谁
obj.p = this
// 给obj添加一个方法,把参数传进去调用 如果有返回值就返回赋值给result
var result = obj.p(...args)
// 添加了之后要删除
delete obj.p
// 返回 result 这个返回值
return result
}
同理,apply 也是一样
Function.prototype.apply = function (obj, args) {
// 如果第一个参数是 null 或者 undefined 赋值为 window
if (obj === null || obj === undefined) {
obj = window
}
// 谁调用call,this就指向谁
obj.p = this
// 给obj添加一个方法,把参数传进去调用 如果有返回值就返回赋值给result
var result = obj.p(...args)
// 添加了之后要删除
delete obj.p
// 返回 result 这个返回值
return result
}
call 和 apply 唯一的不同点就是,接受的参数类型不用,一个是解构后的值,一个是没解构的数组
(六)bind
bind 返回的是一个新的函数
Function.prototype.bind = function (obj, ...args) { // bind 函数传参数
// bind 返回一个新函数
return (...arg2s) => { // 新函数传参数
return this.call(obj, ...args, ...arg2s) // call 返回一个返回值,将返回值返回
}
}
bind 有两种传参数方式
person.bind(me, 1, 2)() // bind 函数传参数
person.bind(me)(1, 2) // bind 返回的新函数传参数
以上就是所有的知识点啦~