Javascript -- call/apply/bind方法

一、call/apply/bind

改变函数执行时,里面this指向对象

call

call()方法里面第一个参数时this指向对象,第二个参数是函数执行时要传入的参数,只能一个一个的传入

const obj = {
  a: '李狗蛋',
  b: '王翠花',
}

function Hello (s) {
  console.log(this)
  console.log('a=' + this.a + 'b=' + this.b + 'c=' + s)
}
Hello()

Hello.call(obj, c)

// 打印结果
window {...}
a=1b=2c=undefined

{a: "李狗蛋", b: "王翠花"}
a=李狗蛋b=王翠花c=3

正常情况下,Hello函数是全局对象window上挂载的一个函数,函数执行时,this应该指向调用它的对象window,但是通过call方法传入了obj对象,让函数里面的this变成了obj对象

浏览器环境或者非严格模式下,如果传入null或者undefined,则this将会指向全局对象window,如果是其他环境,如node,this则指向global

// 注意声明变量时,一定要用var,如果用const,let,则会显示undefined
// 通过var,相当于在window全局对象上声明了a和b两个属性
var a = 1
var b = 2
const c = 3

function Hello (s) {
  console.log(this)
  console.log('a=' + this.a + 'b=' + this.b + 'c=' + s)
}
Hello.call(null, c)

// 打印结果
window{...}
a=undefinedb=2c=3

如果是在严格模式下,this将不会发生改变,传入什么就是什么

// 严格模式
'use strict'
var a = 1
var b = 2
const c = 3

const obj = {
  a: '李狗蛋',
  b: '王翠花',
}

function Hello (s) {
  console.log(this)
  console.log('a=' + this.a + 'b=' + this.b + 'c=' + s)
}
Hello.call(null, c)

// 打印结果
null
报错:Cannot read property 'a' of null at Hello

apply

aplly方法是用来改变函数执行时this指向对象,方法有两个参数,第一个参数是this指向的对象,第二个参数是函数执行时要传入的参数,必须是一个数组

var a = 1
var b = 2
const c = 3

const obj = {
  a: '李狗蛋',
  b: '王翠花',
}

function Hello (s) {
  console.log(this)
  console.log('a=' + this.a + 'b=' + this.b + 'c=' + s)
}
Hello(c)

Hello.apply(obj, [c])

// 打印结果
window {...}
a=1b=2c=3

{a: "李狗蛋", b: "王翠花"}
a=李狗蛋b=王翠花c=3

可以看到同call一样,正常情况下,Hello函数是全局对象window上挂载的一个函数,函数执行时,this应该指向调用它的对象window,但是通过apply方法传入了obj对象,让函数里面的this变成了obj对象

浏览器环境或者非严格模式下,如果thisArg传入null或者undefined,则this将会指向全局对象window,如果是其他环境,如node,this则指向global

var a = 1
var b = 2
const c = 3

const obj = {
  a: '李狗蛋',
  b: '王翠花',
}

function Hello (s) {
  console.log(this)
  console.log('a=' + this.a + 'b=' + this.b + 'c=' + s)
}

Hello.apply(undefined, [c])

// 打印结果
window {...}
a=1b=2c=3

如果是在严格模式下,thisArg将不会发生改变,传入什么就是什么

'use strict'

var a = 1
var b = 2
const c = 3

const obj = {
  a: '李狗蛋',
  b: '王翠花',
}

function Hello (s) {
  console.log(this)
  console.log('a=' + this.a + 'b=' + this.b + 'c=' + s)
}

Hello.apply(undefined, [c])

// 打印结果
undefined
报错:Cannot read property 'a' of undefined at Hello

bind

bind也是用来改变thisArg指向对象的,第一个参数是函数执行时的thisArg指向对象,第二个对象是传入到函数里面的参数,这个方法同call差不多

Tips

Tips

Tips

1、bind是返回一个函数,而不是像callapply一样立即调用,而是需要手动去调用触发函数

2、bind传入的参数并不等同于原函数传入的参数,而是在原函数的参数前面作为新增参数,添加进去,原来参数多余的就清除掉

var a = 1
var b = 2
const c = 3

const obj = {
  a: '李狗蛋',
  b: '王翠花',
}

function Hello (s, d, k) {
  console.log(this)
  console.log('a=' + this.a + 'b=' + this.b + 'c=' + s + 'd=' + d + 'e=' + k)
}
Hello()

Hello.bind(obj, c)(7, 8, 9)

// 打印结果
window {...}
a=1b=2c=undefinedd=undefinede=undefined
        
{a: "李狗蛋", b: "王翠花"}
a=李狗蛋b=王翠花c=3d=7e=8 // 9没了,因为只有三个形参位置,bind加了一个,最后的9就要清除掉

浏览器环境或者非严格模式下,如果thisArg传入null或者undefined,则this将会指向全局对象window,如果是其他环境,如node,this则指向global

var a = 1
var b = 2
const c = 3

const obj = {
  a: '李狗蛋',
  b: '王翠花',
}

function Hello (s, d, k) {
  console.log(this)
  console.log('a=' + this.a + 'b=' + this.b + 'c=' + s + 'd=' + d + 'e=' + k)
}

Hello.bind(undefined, c)(7, 8, 9)

// 打印结果
window {...}
a=1b=2c=3d=7e=8

如果是在严格模式下,thisArg将不会发生改变,传入什么就是什么

'use strict'

var a = 1
var b = 2
const c = 3

const obj = {
  a: '李狗蛋',
  b: '王翠花',
}

function Hello (s, d, k) {
  console.log(this)
  console.log('a=' + this.a + 'b=' + this.b + 'c=' + s + 'd=' + d + 'e=' + k)
}

Hello.bind(undefined, c)(7, 8, 9)

// 打印结果
undefined
报错:Cannot read property 'a' of undefined at Hello
posted @ 2019-06-01 15:39  不会代码的前端  阅读(302)  评论(0编辑  收藏  举报