美文网首页
改变this的方法

改变this的方法

作者: 海山城 | 来源:发表于2017-12-07 16:22 被阅读0次

bind

bind,在Function.prototype上,返回一个新函数,并且使函数内部的this为传入的第一个参数

用法

var name = 'globle'
var App = {
  name: 'app',
  sayName: function(){
    console.log(this.name)
  }
}

var obj = {
  name: 'SeaMountC'
}

App.sayName()                     //"app"
App.sayName.bind(window)()        //"globle"
App.sayName.bind(obj)()           //"SeaMountC"

使用场景

var Page = {
  init: function(){
    this.node = document.body
    this.bind()
  },
  bind: function(){
    this.node.addEventListener('click', function(){
      this.sayHello()//①
    })
  },
  sayHello: function(){
    console.log('hello...' + this.node.innerText)
  }
}
Page.init() //报错

上述代码会报错,因为①处的this指的是this.node,而不是我们期待的Page,而document.body中并没有sayHello方法,所以报错。
修改方法:
第一种:将this存下来

var Page = {
  init: function(){
    this.node = document.body
    this.bind()
  },
  bind: function(){
    var _this = this
    this.node.addEventListener('click', function(){
      _this.sayHello() 
    })
  },
  sayHello: function(){
    console.log('hello...' + this.node.innerText)
  }
}
Page.init() //"hello...海山城"

参考前一遍写的this的判断方法,_this.sayHello() 相当于Page.sayHello.call(Page),因此sayHello中的this是指Page,没有问题

第二种:使用bind改变this

var Page = {
  init: function(){
    this.node = document.body
    this.bind()
  },
  bind: function(){
    this.node.addEventListener('click', function(){
      this.sayHello()
    }.bind(this))
  },
  sayHello: function(){
    console.log('hello...' + this.node.innerText)
  }
}
Page.init()

第三种:换种写法,同样使用bind改变this

var Page = {
  init: function(){
    this.node = document.body
    this.bind()
  },
  bind: function(){
    this.node.addEventListener('click', this.sayHello.bind(this))
  },
  sayHello: function(){
    console.log('hello...' + this.node.innerText)
  }
}
Page.init() //"hello...海山城"

注:

  • 注意这种写法,是直接将sayHello作为click事件的回调函数
  • 这种方法如果不bind(this),会报错,因为sayHello中的this指的是document.body,最后就变成document.body.node.innerText

apply、call

bind与apply、call相同点:

  • 都是用来改变函数的this对象的指向的;
  • 第一个参数都是this要指向的对象;
  • 都可以利用后续参数传参;

bind与apply、call区别:

  • bind不会立即调用,其他两个会立即调用
  • 因为bind不会立即调用,因此可以有两种传参形式,
    一种是向call一样fn.bind(context, param1, param2...)()
    另一种是fn.bind(context)(param1, param2...)

apply与call区别:

  • call方法接收参数列表fn.call(context, param1, param2...),而apply接收参数数组fn.apply(context, paramArray)

使用事例1
求和函数,直接arguments.forEach会报错,借用数组的forEach方法,通过call将forEach内部的this从数组改成arguments

function sum(){
//   ------------------报错-----------------
//   arguments.forEach(function(value){
//     console.log(value)
//   })
//   --------------------------------------
  
  var result = 0
  Array.prototype.forEach.call(arguments, function(value){
    console.log(value)
    result += value
  })
  console.log(result)
}
sum(9,5,4,3)
  • forEach正常调用形式为[1,2,3].forEach(function(val){}),相当于[1,2,3].forEach.call([1,2,3], function(val){}),因此forEach中的this指的是数组本身
  • Array.prototype.forEach(function(val){}),相当于Array.prototype.forEach.call(Array.prototype, function(val){}),这样forEach方法中的this指的是Array.prototype,将第一个参数改成arguments,即可改变forEach方法中的this,相当于此时forEach方法中的代码都是针对arguments处理的
  • 因此[1,2,3].forEach.call([1,2,3], function(val){}),可以写Array.prototype.forEach.call([1,2,3], function(val){})

使用事例2
将arguments变成数组,这样就可以使用数组的方法了

function argsToArray(){
  var args = Array.prototype.slice.call(arguments, 0)
  console.log(args instanceof Array) //true
}
argsToArray(1,3,4,5,6)

使用事例3
借用Math.max(),Math.min()方法,求数组最大,最小值

var arr = [5, 0, 2, 9]
//------正常是这么调用的-------------
//Math.max(5, 0, 2, 9)
//-------------------------------------------

//使用apply
Math.max.apply(Math, arr)
Math.max.apply(null, arr)
  • 上面apply的context参数(第一个参数)无所谓是什么,max方法本来就是针对传入的参数做处理的,而不是针对传入的this。
  • apply传入的第二个参数是数组,如果是call的话,就得这样Math.max.call(null, 5, 0, 2, 9)

相关文章

  • 改变的方法

    穷人改变命运,唯一方法就是努力的工作,勤奋的工作。稻盛和夫说,付出不亚于任何人的努力,对待工作才有可能获得成功才能...

  • 改变的方法

    用心里免疫X光片看到内心重大假设之后,就要做出改变,课程介绍了四原则,希望可以对你有用。 获得新经验,引发改变 文...

  • 改变的方法

    今天宁教授分享的是《认知不协调》,在目前很多人都在高调地说“知行合一”,可是做到的人却很少,大部分人都存在着认知不...

  • 改变this的方法

    bind bind,在Function.prototype上,返回一个新函数,并且使函数内部的this为传入的第一...

  • 改变的方法

    如何才能引爆孩子学习力,让孩子主动爱上学习? 对前面内容的总结我们不难得出一个结论: 孩子是否主动学习,来源于在孩...

  • 改变的方法

    思维决定行为,行为决定习惯,习惯决定性格,性格决定命运。 一个人要想改变,首先得先改变自己的思维和认知,并且时刻保...

  • D005+8组菩提释+《如何有效阅读一本书》第五章

    写读书笔记可以改变读书方法,而读书方法的改变又会带来思考方式的改变 ...

  • js数组中哪些方法可以改变原始数组,哪些不会改变

    会改变原始数组的方法有: 不改变原始数组的方法有:

  • 07-23箭头函数this指向

    使用call方法改变this方法 通过对象的方式改变函数里的this的指向

  • iOS Swift 改变Label文字位置和Button图文位置

    改变Label文字位置 通过重写drawText方法,改变frame位置,后面延展方法是改变文字间的间距 改变UI...

网友评论

      本文标题:改变this的方法

      本文链接:https://www.haomeiwen.com/subject/edukixtx.html