call、apply和bind

2018-01-27  本文已影响0人  没头脑很不高兴

看一段代码先

function add(a, b) {
  return a + b
}
add(1, 2) // 3

上面的add(1, 2)就是调用(或者执行)add函数,这是JavaScript里面最为常见的调用函数的方式。

call、apply和bind,他们也都是调用函数的方式

使用call调用函数

上面的add(1, 2),括号里面的1和2是穿进去的参数,是实参,在使用call调用函数时,参数的第一个需要插入一个 "东西",这个"东西"是一个对象,后面的参数接着往后挤一下,看一下使用的方式:

var o = {
  a:1
}
a = 2
function test() {
  console.log(this.a)
}
test() // 2

这里的this指向window,而 a = 2是window上的变量,所以输出2
再换一段代码

var o = {
  a:1
}
a = 2
function test() {
  console.log(this.a)
}
test.call(o) //1

这里会输出1
因为使用 call 执行函数的时候,call 的第一个参数会变成函数里面的this
this是一个会变的东西,大多数情况下都需要根据不同的环境来推测this是什么对象
而且,在古老的汇编语言中,就是使用call 来调用函数的
因此,在有this存在的函数中,可以使用call 来调用函数,强制指定this

使用apply调用函数

apply的使用方式和call类似,都会指定函数内部的this,区别是:当参数过多或者参数不明确时,需要使用apply
代码


function log(){
  return console.log.apply(console, arguments)
}

这个函数定义了一个自己的log函数,console 也是一个对象,log是console对象内的一个方法,arguments是实参列表(传进来的参数形成的类数组)
这样,在使用log函数的时候可以少写几个字,当代码中的log函数过多时,并且上线的代码不能有log,可以把上面的log函数改成这样

function log(){}

把log函数变成一个空的,下面代码中所有的log函数也就失效了

bind

看一段代码:

var log = console.log.bind(console)

这段代码和上面定义的log函数是一样的功能,这里的log也是一个函数,并不是一个对象,因为bind写在函数体后的时候,会形成一个新的函数,定义的log就是就收这个新函数的
bind还有另外一个功能,和前面一样,第一个参数会改变函数内this的指向

var d = document.querySelector('div')
var o = {
  a: 2,
  click:function(){
    d.onclick = function(){
      console.log(this.a)
      this.a ++
    }
  }
}
o.click()

这段代码的目的是想使div在点击的时候,让 o 对象内的a ++,但是实际上却做不到,因为onclick函数内的this会指向被绑定事件的节点对象,也就是这个div,想让this 变成 o 对象,可以使用bind 方法

var d = document.querySelector('div')
var o = {
  a: 2,
  click:function(){
    d.onclick = function(){
      console.log(this.a)
      this.a ++
    }.bind(this)
  }
}
o.click()

这样,onclick 函数内部的this ,就是全是外部 提供的

上一篇下一篇

猜你喜欢

热点阅读