让人头疼的this

版权声明:本文为博主原创文章,转载请附上原文地址 https://blog.csdn.net/writing_happy/article/details/83351752

this是什么

  this是函数运行时所在的环境变量,是call的第一个参数。

  以及你需要注意的是,this这个鬼东西动不动就会变成window。

怎么找this

作为对象方法调用

var obj = {
  'fn': function(){
    console.log(this)
  }
}
obj.fn()

  此时打印出来的this指的是obj这个对象。在函数作为对象方法调用的时候,this指的是调用这个函数的对象。

全局函数调用

  所谓全局函数调用,区分于作为对象方法调用。

function fn(){
  console.log(this)
}
fn()

  此时打印出来的是window。在函数作为全局函数调用的时候,this指的是window。

  如果是在严格模式下,则默认是undefined。

'use strict'
function fn(){
  console.log(this)
}
fn()  //undefined

作为构造函数调用

function A(){
  return this
}
var a = new A()
console.log(a)

  此时的this指的是这个新new出来的对象。虽然这样看起来理所当然,但是好像情况变复杂的话就容易出问题。暂且不提。

如果你搞不清楚上边的三种情况,那么请记住,this是call的第一个参数。

  确切地说,call、apply以及bind的第一个参数。关于call、apply和bind的区别很多地方都有写,这里简单提一下,call和apply都是直接调用该函数,不同的是call把所有参数一次传进去,而apply的话,第一个参数是this,第二个参数是函数内部真正需要传递的参数构成的数组(或者是一个伪数组)。而bind的话,是绑定this并返回一个函数,不会直接进行函数调用。

var obj1 = {name: 'wcy'}
var obj2 = {name: 'whw'}
function fn(){
  console.log(this)
}
var fn2 = fn.bind(obj1)
fn2.call(obj2)  //此时即使你传入了obj2,得到的结果也是obj1,因为fn2的this已经被bind绑定了。

  如果把call调用套在上边的方法中的话,那么我们可以不需要分类更简单粗暴地得到this的值。

var obj = {
  'fn': function(){
    console.log(this)
  }
}
var obj1 = {name: 'wcy'}
var obj2 = {name: 'whw'}
var fn2 = obj.fn
obj.fn.call()    
fn2.call()   //call不写参数,在非严格模式下默认值是window,this指向window。在严格模式下默认没有传参数,所以是undefined。
obj.fn.call(obj)   //call的第一个参数是obj,所以this是obj
fn2.call(obj1)   //call的第一个参数是obj1,所以this是obj1

  那么,如果call的第一个参数传的就是this呢?比如下面这样

function X(){
  return object = {
    name: 'object',
    fn1(x){
      x.fn2.call(this)    //这里传入的this指的就是当前的对象,也就是object。如果你不使用call调用的话,那么调用的是options中的fn2,输出结果也是options对象。
    },
    fn2(){
      console.log('A')
      console.log(this)   //A
    }
  }
}
var options = {
  name: 'options',
  fn1(){},
  fn2(){
    console.log('B')
    console.log(this)    //B
  }
}
var x = X()
x.fn1(options)   //此时输出的结果应该是B  object对象

猜你喜欢

转载自blog.csdn.net/writing_happy/article/details/83351752