资讯专栏INFORMATION COLUMN

call() 与 apply() 和 bind()

DTeam / 1470人阅读

摘要:但是当构造函数显示返回一个对象时就会将这个对象赋值给变量,的使用则无效。将参数全都传入,它会把参数作为数组传入。

首先了解this

如果想用好这几个方法,需要先了解this被调用方式不同而导致值不同的各种情况,然后就会认识到使用这几个方法的原因在哪里。(可以指定this的值)
全局上下文中this指向全局对象,函数上下文this取决于被调用的方式

例:

在非严格模式下,全局调用函数this默认指向全局(window)

var a = 3

function exp(){
  var a = 4
  console.log(this.a)
}

var b = exp()
// 输出3

在严格模式下,因为this为其进入上下文时的值,所以为undefined

function exp(){
 "use strict"
  return this
}

console.log(exp() === undefined)
// 输出 true

下面分析各个调用场合下this的值

作为函数被直接调用

上面已经写出了这种情况,值得注意的是,我们往往并不需要this值为window

作为方法被调用

作为方法被调用时,this指向方法所在的对象上
例:

var exp =  {
  obj: function context() {
     var text = "hello"
     return this 
  }
}

console.log(exp.obj() === exp)
var a = exp.obj()
console.log(a === exp)

var b = exp.obj
console.log(b() === window) //true,,注意这里当对象的方法被全局调用后this是b的this,则是window

//均输出 true
作为构造函数被调用

我们知道构造函数创建一个对象的过程

创建新对象

新对象作为this指向的对象

为新对象添加方法、属性、、并返回对象

需要注意的地方:构造函数返回一个非对象类型时,创建新对象时并不妨碍this的使用,也会返回新创建的对象。但是当构造函数显示返回一个对象时就会将这个对象赋值给变量,this的使用则无效。

function Fn (){
  this.obj = function() {
    return this
  }
}

let a = new Fn()
console.log(a.obj() === Fn) // false
console.log(a.obj() === a) //true

let newObj = {
  name: "小明"
}

function reObj (){
  this.name = "康康"
  return newObj
}

let b = new reObj()
console.log(b.name) //小明,返回的对象是newObj

进入正题,在这么多变化中随时都可能出错,所以call()、apply()、bind()就提供了一个可以指定this的方式

方法的使用

call()

这个方法接受多个参数,第一个参数是指定的this值,剩下的都是调用的函数的参数列表
fn.call(this, arg1, arg2, ...);
如果第一个参数需要是对象,如果传入了数字、字符串、布尔值的话this会指向该原始值的自动包装对象

function f(){
      console.log(this)
      console.log(arguments)
  }
  f.call() // window
  f.call({name:"小明"}) // {name: "小明"}, []
  f.call({name:"小红"},1) // {name: "小红"}, [1]
  f.call({name:"康康"},1,2) // {name: "康康"}, [1,2]

apply()

apply() 与call()区别在于第二个参数接受的是一个包含多个参数的数组,对于一些方法需要传入的参数不能使数组,可以使用apply()调用函数使其可以使用数组作为参数。

var a = [1,2,3,4,5,6,7,8,9]
sum.apply(null,a)
//将参数a全都传入,它会把参数作为数组传入。

//求数组的最大元素
Math.max.apply(null,[1,2,6]) // 6

很多使用场景都可以被es6里的扩展运算符替代

bind()

bind()方法创建一个新的函数, 当被调用时,将其this关键字设置为提供的值.

this.name = "大牛"

let obj = {
  name: "康康",
  age: 18,
  city:"上海"
}

let newObj =  {
  name: "小明",
  sayName: function() {
    console.log(this.name)
  }
}

newObj.sayName()// 小明

let a = newObj.sayName.bind(obj)
a() //康康

let b = newObj.sayName
b() //大牛

箭头函数
这里说一下箭头函数,因为箭头函数没有this,所以会根据作用域链进行寻找this,这也衍生了很多用法,比如在setTimeout里经常出现的上下文(作用域)问题,如果不使用箭头函数,在函数运行时作用域就变成了全局,使用箭头函数会使函数里用到的this绑定在setTimeout的作用域上

var timer = {
fn1() {
    setTimeout(function(){
        console.log(this)
    }, 10)
},
fn2() {
    setTimeout(()=>{
        console.log(this)
    },20)
},
fn3: ()=> {
    setTimeout(()=>{
        console.log(this)
    },30)        
}
 }
 timer.fn1() //window
 timer.fn2() // timer
 timer.fn3() //window
 
 //第一个在执行时是在全局调用,相当于 fn1.call(undefined)
 // 第二个使用箭头函数自身没this,使this 指向了timer
 // 第三个自身没this的情况下,根据箭头函数的规则找到了最外层全局(window)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/107691.html

相关文章

  • bindcallapply的区别实现原理

    摘要:简单说一下的区别三者都是用于改变函数体内的指向,但是与和的最大的区别是不会立即调用,而是返回一个新函数,称为绑定函数,其内的指向为创建它时传入的第一个参数,而传入的第二个及以后的参数作为原函数的参数来调用原函数。原文链接的区别与实现原理 1、简单说一下bind、call、apply的区别   三者都是用于改变函数体内this的指向,但是bind与apply和call的最大的区别是:bi...

    oliverhuang 评论0 收藏0
  • javascript中call(),apply().bind()方法的作用异同

    摘要:原文章发表在的个人博客一细节中函数存在定义时上下文,运行时上下文上下文是可变的为改变某个函数运行时的上下文而存在的,换句话说,是为了改变函数内部的指向没有方法,但是有呀所以可以去把方法的运行时上下文也就是运行时的的指向,指向这个时候低啊用 原文章发表在 Klay-Clam的个人博客 一、细节 javascript 中函数存在定义时上下文,运行时上下文 上下文是可变的 1. call...

    Near_Li 评论0 收藏0
  • 「干货」细说 callapply 以及 bind 的区别用法

    摘要:的调用者,将会指向这个对象。此外,还可以扩展自己的其他方法。的使用最后来说说。不同的是,方法的返回值是函数,并且需要稍后调用,才会执行。而和则是立即调用。总结和的主要作用,是改变对象的执行上下文,并且是立即执行的。 前言 上一篇文章 《「前端面试题系列4」this 的原理以及用法》 中,提到了 call 和 apply。 它们最主要的作用,是改变 this 的指向。在平时的工作中,除了...

    GraphQuery 评论0 收藏0
  • js 面试官想了解你有多理解call,apply,bind?

    摘要:返回值这段在下方应用中有详细的示例解析。回调函数丢失的解决方案绑定回调函数的指向这是典型的应用场景绑定指向,用做回调函数。 showImg(https://segmentfault.com/img/remote/1460000019971331?w=1024&h=680); 函数原型链中的 apply,call 和 bind 方法是 JavaScript 中相当重要的概念,与 this...

    wuaiqiu 评论0 收藏0
  • call() , apply() bind() 实例详解

    摘要:当没有使用而直接调用时指向对象函数和函数非常的相似,第一个参数都用来设置目标函数运行时的指向。输出的结果为结果证明两个地方传入的参数都会被传给目标函数,函数拷贝调用时传入的参数会追加在函数调用时传入的参数后面。 call() , apply() 与 bind() 详解 我们知道可以用call(), apply() 和 bind()这三个函数都是用来完成函数调用,并且设置this指向。 ...

    wayneli 评论0 收藏0

发表评论

0条评论

DTeam

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<