Js中this指向问题总结

this的默认指向

  1. 全局环境下的this指向了window

    console.log(this) // window
    
  2. 函数独立调用,函数内部的this也指向了window

    function fn(){
           
      console.log(this) // window
    }
    
  3. 被嵌套的函数独立调用时,this默认指向了window

    var a= 0;
    var obj= {
           
      a: 2,
      foo: function (){
           
      	//函数当做对象的方法来调用this指向了obj
        var that = this;
        function test(){
            
          console.log(that.a); // 2
        	console.log(this.a); // 0
        }
      	test();
      }
    }
    
    obj.foo();
    
  4. IIFE 自调用函数内部的this也指向window

  5. 闭包this默认指向了window

    var a= 0;
    var obj= {
           
      a: 2,
      foo: function (){
           
      	var that = this;
        return function test(){
           
          return this.a
        }
      }
    }
    var fn = obj.foo();
    console.log(fn()); // 0
    

隐式绑定

当函数当做方法来调用,this指向了直接对象

function foo(){
      
	console.log(this.a);
}
var obj = {
     
  a: 1,
  foo: foo,
  obj2:{
     
		a: 2,
    foo: foo
  }
}
// foo()函数的直接对象是obj, this的指向指向了直接对象
obj.foo(); // 1
// foo()函数的直接对象是obj2,this的指向指向了直接对象
obj.obj2.foo(); // 2

隐式丢失

隐式丢失就是指被隐式绑定的函数丢失了绑定对象从而默认绑定到window

这种情况比较容易出错却又非常常见

函数别名

var a = 0;
function foo(){
     
  console.log(this.a)
}
var obj = {
     
  a: 1,
  foo: foo
}
// 把obj.foo()赋值给别名bar,造成隐式丢失的情况。因为只是把obj.foo()赋值了bar变量。而bar与obj对象毫无关系
var bar = obj.foo();
bar(); // 0

参数传递

var a = 0;
function foo(){
     
  console.log(this.a)
}
function bar(fn){
     
  fn()
}
var obj = {
     
  a: 1,
  foo: foo
}
// 把obj.foo当做参数传递到bar函数中,有隐式的函数赋值fn=obj.foo,只是把foo函数赋值给了fn,而fn与obj对象毫无关系,所以当前foo函数内部的this指向了window
bar(obj.foo) // 0

内置函数

var a = 0;
function foo(){
     
  console.log(this.a)
}
var obj = {
     
  a: 1,
  foo: foo
}
// setTimeout( )和setInterval()第一个参数的回调函数中的this默认指向了window,跟第二种情况是累死
setTimeout(obj.foo, 1000) // 0

间接调用

var a = 0;
function foo(){
     
  console.log(this.a)
}
var obj = {
     
  a: 1,
  foo: foo
}
var p = {
     
  a: 2
}
// 隐式绑定,函数当做对象中的方法来使用,内部的this指向了该对象
obj.foo() //1
// 将obj.foo函数对象赋值给p.foo函数,然后立即执行。相当于仅仅是foo()函数的立即调用,内部的this默认指向了window
(p.foo = obj.foo)() // 0
// 将obj.foo赋值给p.foo函数,之后p.foo()函数再执行,其实是属于p对象的方法的指向,this指向了当前的p对象
p.foo = obj.foo
p.foo() // 2

显式绑定

显式绑定

call(), apply(), bind()把对象绑定到this上,叫做显示绑定

var a = 0;
function foo(){
     
  console.log(this.a)
}
var obj = {
     
  a: 1,
  foo: foo
}

foo() // 0
foo.call(obj) // 1
foo.apply(obj) // 1
foo.bind(obj) // 1

硬绑定

硬绑定是显示绑定的一个变种,使得this不能再被改变

var a = 0;
function foo(){
     
  console.log(this.a)
}
var obj = {
     
  a: 1,
  foo: foo
}
var bar = function(){
     
  foo.call(obj)
}
bar(); // 1
setTimeout(bar, 1000) // 1

数组的forEach map()…

var id = 'window';
function fn(el){
     
	console.log(el, this.id);
}
var obj={
     
  id: fn
}
var arr = [1,2,3];
arr.forEach(fn); // this指向window
arr.forEach(fn,obj); // this指向obj

new绑定

1.如果是new关键来执行函数相当于构造函数来实例化对象,那么内部的this指向了当前实例化的对象

function fn(){
     
	console.log(this);
}
var fn = new fn();
console.log(fn); // fn
var person = {
     
	fav: function (){
     
		return this;
  }
}
var p= new person.fav();
console.log(p); // fav
// 实例化出来的对象内部的属性 constructor属性指向了当前的构造函数
console.log(p.constructor == person.fav) // true

严格模式下this的指向

独立调用的函数内部的this指向了undefined

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

严格模式下,函数apply()call()内部的this始终是它们的第一个参数

var color = 'red'
function showColor(){
      
  'use strict'
  console.log(this)
  console.log(this.color)
}
showColor.call(undefined)

你可能感兴趣的:(JavaScript,js,javascript,前端)