关于js中的this指向问题

每一个函数的this是在函数执行时绑定的,彻底取决于函数的调用位置(函数执行时地方)。 我把js中的this指向分为如下5大类数组

默认绑定

默认绑定时是把this绑定在window上; 若是使用严格模式,则会绑定到undefined上bash

function foo(){
	console.log(this.a)
}
var a = 2
foo() // 2

复制代码

这里的this就绑定在window上,若是使用严格模式,则this指向的是undefinedapp

function foo(){
	'use strict'
	console.log(this.a)  // typeError:this is undefined
}
var a = 2
foo() // 2

复制代码

隐式绑定

隐式绑定指的是在调用的位置是否有上下文关系(是否被某个对象所包含),这种状况下谁调用指向谁函数

function foo(){
    console.log(this.a)
}

var obj = {
    a:2,
    foo: foo
}

obj.foo()  // 2 
// 因为调用者是obj这个对象,因此foo中的this.a指向obj.a
复制代码

一个多级对象在调用方法时,this绑定在离他最近的那个对象上ui

function foo(){
    console.log(this.a)
}

var obj = {
    a:2,
    foo: foo
}

var obj1 = {
    a:3,
    obj:obj
}

obj1.obj.foo() // 2
复制代码

此外,隐式绑定有一种特殊状况,就是隐式丢失 当并非直接调用某个函数或方法时,这时候会出现this绑定丢失的状况。 如下是几种绑定丢失的状况this

  1. 给函数起别名
function foo(){
    console.log(this.a)
}

var obj = {
    a:2,
    foo: foo
}

var baz = obj.foo

var a = 'baz'
baz() // baz

// baz函数实际上引用的是foo函数自己,所以这时候使用了默认绑定
复制代码
  1. 函数做为另外一个函数的回调
function foo(){
    console.log(this.a)
}

var obj = {
    a:2,
    foo: foo
}

function doFoo(fn){
    fn()
}
var a = 'baz'
doFoo(obj.foo)  // baz
复制代码

显式绑定

显示绑定是指经过call/apply/bind绑定的this。spa

他们的区别主要以下:prototype

  • call: 第一个参数是被绑定的this对象,以后依次写要传的函数参数
  • apply: 第一个参数是被绑定的this对象,以后是一个数组,须要的参数传入这个数组
  • bind:bind返回的是一个函数,须要加()再次执行

new绑定(构造函数绑定)

经过 new 构造的函数实例,this绑定在当前实例上code

function Foo(a){
    this.a = a
}

var foo = new Foo(2)
console.log(foo.a) // 2
复制代码

关于构造函数new的过程,主要分为如下四步: 1.建立一个对象 2.构造这个对象的prototype等属性 3.将这个对象绑定到this 4.返回这个对象对象

箭头函数中的this

箭头函数没有本身的 this,当在内部使用了 this时,它会指向最近一层做用域内的 this,箭头函数的this在定义时就肯定了。

var name = 'xiaohong';
var obj = {
    name: 'xm',
    sayName: () => {
        console.log(this.name) 
    }
}
obj.sayName() // xiaohong
复制代码

此时的箭头函数和sayName是同级的,它属于obj,因为箭头函数没有this,因此它的this指向离它最近的做用域的this,即指向window。

var obj = {
    name: 'xm',
    sayName: function(){
        return () => {
            console.log(this.name);
        }
    }
}
obj.sayName()()          //xm
复制代码

因为箭头函数没有本身的 this,当在内部使用了 this时,它会指向最近一层做用域内的 this,箭头函数的最近一层的做用域为obj内,因此它的this指向obj

var obj = {
    name: 'xm',
    sayName: function(){
        return () => {
          return () => {
            return () => {
              console.log(this.name);
            };
          };
       };
    }
}
obj.sayName()()()() // xm
复制代码

以上函数定义了三个箭头函数,因为三个箭头函数都不存在this,因此它的this指向了离箭头函数最近的obj.

相关文章
相关标签/搜索