this

apply、call 有什么作用,什么区别

要说清除apply和call的作用就要从this的指向开始讲起

  • this值的指向
    this, 是函数内部的属性, 指向的函数据以执行的环境对象, 注意: this的指向只有函数调用的时候才能确定
    1. 在全局调用的时候指向的是window
    2. 作为对象的方法调用的时候指向的是那个对象
    3. 构造函数的时候指向的是构造出来的对象
    4. 在事件的回调函数中指的是注册事件dom节点(this === e.currentTarget)
    5. 只用apply和call调用的时候指向的是第一个参数指定对象, 如果第一个null就指向window

例子:

var name = 'hello'
var obj = {
  name: 'world'
}

function sayName() {
  console.log(this.name)
}
//全局调用, 默认指向window
sayName()//输出'hello'
//作为obj的方法调用, 指向obj
obj.sayName = sayName
obj.sayName()//输出'world'
//使用call指定this值
sayName.call(obj)//输出'world'
  • apply和call的作用
    apply和call的作用是相同的, 都是指定函数的this值和参数调用函数, 其实JavaScript完全可以不支持使用.调用函数的方法, 例如obj.sayName(), 这只是一个语法糖, 使得this的指向去不够清晰, 而使用apply和call调用却使this的指向十分清晰
    例如:
sayName.call(null)//如果不指定, 函数内部的this指向的就是window
sayName.call(obj)//指定this的指向为obj
  • apply和call的区别
    区别在于传递给函数的参数, apply接受的是数组形式, call接受的是多个参数, 因为apply接受数组形式的参数, 所以就有一些特别的用法, 例如
var numArr =[1,2,3,4,5,6,7]
Math.min.apply(null, numArr)//就可以获得数组中的最小值
Math.max.apply(null,numArr)//就可以获得数组中的最大值

注意: 虽然apply接受的是数组, 但是传递给函数的参数还是数组的元素, 而不是整个数组

代码练习题

//1. 以下代码输出什么?
var john = {
  firstName: "John"
}
function func() {
  alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi()
//输出"John: hi!"

//2. 下面代码输出什么,为什么
func()

function func() {
  alert(this)
}
//输出window, 因为func()是在全局环境下调用的, 全局环境绑定的是window对象

//3. 下面代码输出什么
function fn0(){
    function fn(){
        console.log(this);
    }
    fn();
}

fn0();//输出window对象


document.addEventListener('click', function(e){
    console.log(this);//输出dom节点document
    setTimeout(function(){
        console.log(this);//输出window对象
    }, 200);
}, false);

//4. 下面代码输出什么,why
var john = {
  firstName: "John"
}

function func() {
  alert( this.firstName )
}
func.call(john)
//"John"
//因为call的第一个参数指定this的值

//5. 代码输出?
var john = {
  firstName: "John",
  surname: "Smith"
}

function func(a, b) {
  alert( this[a] + ' ' + this[b] )
}
func.call(john, 'firstName', 'surname')
//输出"John Smith"

//6. 以下代码有什么问题,如何修改
var module= {
  bind: function(){
    $btn.on('click', function(){
      console.log(this) //this指什么, 当$btn被点击的时候, this指向$btn
      this.showMsg();
    })
  },

  showMsg: function(){
    console.log('饥人谷');
  }
}
//问题: this指向只有当函数调用是才确定, 当$btn点击的时候, this指的是$btn, 而不是module
//修改:
var module= {
  bind: function(){
    var that = this
    $btn.on('click', function(){
      console.log(that)
      that.showMsg();
    })
  },

  showMsg: function(){
    console.log('饥人谷');
  }
}

你可能感兴趣的:(this)