call、apply和bind方法的用法以及区别
前言
最近在学习的时候,遇见了apply()函数,发现自己对于call,bind函数不了解,所以今天来看看。
正文
因为这三个函数的作用都是改变函数运行时this的指向,所以我们要来先看看this。
函数调用有以下几种方法:
方法调用模式:
当一个函数被保存为对象的一个方法时,如果调用表达式包含一个提取属性的动作,那么它就是被当做一个方法来调用,此时的this被绑定到这个对象。
var a = 1
var obj = {
a: 2,
fn(){
return this.a;
}
}
console.log(obj.fn()); //2
DOM对象绑定事件也属于方法调用模式,因此它绑定的this就是事件源DOM对象。
document.addEventListener('click',function(){
console.log(this); //document
setTimeout(function(){
console.log(this); //window
},100)
},false)
函数调用模式:
就是普通函数的调用,此时的this被绑定到window
普通的函数调用:
function fn1(){
console.log(this)//window
}
fn1()
把函数赋值之后在调用:
var a = 1
var obj1 = {
a:2,
fn:function(){
console.log(this.a)
}
}
var fn1 = obj1.fn
fn1()//1
这里obj1.fn是一个函数function(){console.log(this.a)},此时fn1就是不带任何修饰的函数调用,function(){console.log(this.a)}.call(undefined),按理说打印出来的 this 应该就是 undefined 了吧,但是浏览器里有一条规则:如果你传的 context 就 null 或者 undefined,那么 window 对象就是默认的 context(严格模式下默认 context 是 undefined) 因此上面的this绑定的就是window,它也被称为隐性绑定。
回调函数
先来看第一个函数:
var a = 1
function f1(fn){
fn()
console.log(a)//1
}
f1(f2)
function f2(){
var a = 2
}
在改写一下这个函数:
var a = 1
function f1() {
(function f2(){
var a =2
})()
console.log(a);
}
仍然是f1.call(undefined)所以this还是window
构造器调用模式:
new一个函数时,背地里会将创建一个连接到prototype成员的新对象,同时this会被绑定到那个新对象上
function Persion(name) {
//这里this指向实例
this.name = name,
this.sayName = function sayName(){
console.log(this.name);
}
}
var a= new Persion('ccc')
a.sayName() //ccc
call函数:
call 方法第一个参数是要绑定给this的值,后面传入的是一个参数列表。当第一个参数为null、undefined的时候,默认指向window。
var arr = [1, 2, 3, 89, 46]
var max = Math.max.call(null, arr[0], arr[1], arr[2], arr[3], arr[4])//89
举一个例子:
var obj = {
message: 'My name is: '
}
function getName(firstName, lastName) {
console.log(this.message + firstName + ' ' + lastName)
}
getName.call(obj, 'Dot', 'Dolby') //My name is: Dot Dolby
apply函数:
apply接受两个参数,第一个参数是要绑定给this的值,第二个参数是一个参数数组。当第一个参数为null、undefined的时候,默认指向window。
var obj = {
message: 'My name is: '
}
function getName(firstName, lastName) {
console.log(this.message + firstName + ' ' + lastName)
}
getName.apply(obj, ['Dot', 'Dolby']) //My name is: Dot Dolby
事实上apply 和 call 的用法几乎相同, 唯一的差别在于:当函数需要传递多个变量时, apply 可以接受一个数组作为参数输入, call 则是接受一系列的单独变量。
bind函数
和call很相似,第一个参数是this的指向,从第二个参数开始是接收的参数列表。区别在于bind方法返回值是函数以及bind接收的参数列表的使用。
- bind返回值是函数
var obj = {
name: 'Dot'
}
function printName() {
console.log(this.name)
}
var dot = printName.bind(obj)
console.log(dot) // function () { … }
dot() // Dot
bind 方法不会立即执行,而是返回一个改变了上下文 this 后的函数。而原函数 printName 中的 this 并没有被改变,依旧指向全局对象 window。
- 参数的使用
function fn(a, b, c) {
console.log(a, b, c);
}
var fn1 = fn.bind(null, 'Dot');
fn('A', 'B', 'C'); // A B C
fn1('A', 'B', 'C'); // Dot A B
fn1('B', 'C'); // Dot B C
fn.call(null, 'Dot'); // Dot undefined undefined
call 是把第二个及以后的参数作为 fn 方法的实参传进去,而 fn1 方法的实参实则是在 bind 中参数的基础上再往后排。
总结
call、apply和bind函数存在的区别:
bind返回对应函数, 便于稍后调用; apply, call则是立即调用。
引用自:
上一篇: Linux服务器下创建新用户两条命令
下一篇: apply,call,bind的基本使用
推荐阅读
-
javascript基于原型链的继承及call和apply函数用法分析
-
Javascript中apply、call、bind的用法讲解
-
浅谈JavaScript中的apply/call/bind和this的使用
-
js中apply()和call()的区别与用法实例分析
-
apply、bind、call方法的作用与区别
-
浅析PHP substr,mb_substr以及mb_strcut的区别和用法
-
浅谈pytorch和Numpy的区别以及相互转换方法
-
apply()和call()的区别
-
JS forEach和map方法的用法与区别分析
-
JavaScript中的split()、substr()、substring()以及slice()和splice()的用法区别