一,判断this指向原则

函数中的this,指向函数运行时所在的对象(当前对象,而不是上层对象)。如果函数运行时没有依赖的当前对象,则this指向最上层对象(eg: window)。

二,this指向的几种情况

1. obj.fun()中的this

指向当前运行的对象obj

fun 中的 this->obj ,自动指向.前的对象

  var obj ={
     foo: function () {
       console.log(this);
     }
   };
   
   obj.foo() // obj

2. new Fun()中的this

指向当前运行的对象(new出来的新实例对象)

Fun 中的 this->正在创建的新对象,new 改变了函数内部的 this 指向,导致 this 指向实例化 new 的对象

    function Person(name) {
      this.name = name;
      console.log(this); // Person {name: "song"}
    };
    
    var person = new Person('song');
    console.log(person.name);// "song" 
    

3. fun()中的this

指向当前运行的对象window

this->最上层对象(eg: window),直接执行函数,this指向默认的最上层对象(eg: window)

    function f() {
      console.log(this);
    }
    f() // window

4. 函数中的函数的this,

没有依赖的当前对象,默认指向window

this->最上层对象(eg: window),因为函数内函数,没有调用它的对象,所以只能指向默认的额window。

例1,函数中的赋值型函数

var o = {
   f1: function () {
     console.log(this);
     var f2 = function () {
       console.log(this);
     }();
   }
 }
 
 o.f1()
 // Object
 // Window (没有调用的它的对象了,所以只能指向默认的额window)
解决办法:保存下this,再为后来用

   ```
   var o = {
      f1: function() {
        console.log(this);
        var that = this;
        var f2 = function() {
          console.log(that);
        }();
      }
    }
    
    o.f1()
    // Object
    // Object
   ```

例2,函数中的回调函数

var o = {
   v: 'hello',
   p: [ 'a1', 'a2' ],
   f: function f() {
     this.p.forEach(function (item) {
       console.log(this.v + ' ' + item);
     });
   }
 }
 
 o.f()
 // undefined a1
 // undefined a2
 // this指向window(因为函数内函数,没有调用它的对象。)
解决办法一:

保存下this,再为后来用

var o = {
  v: 'hello',
  p: [ 'a1', 'a2' ],
  f: function f() {
    var that = this;
    this.p.forEach(function (item) {
      console.log(that.v+' '+item);
    });
  }
}

o.f()
// hello a1
// hello a2
解决办法二:

将this当作foreach方法的第二个参数,固定它的运行环境。

var o = {
  v: 'hello',
  p: [ 'a1', 'a2' ],
  f: function f() {
    this.p.forEach(function (item) {
      console.log(this.v + ' ' + item);
    }, this);
  }
}

o.f()
// hello a1
// hello a2
解决办法三:箭头函数

(箭头函数没有自己的this,this指向定义时所在的对象,而不是运行时所在的对象)

   var o = {
     v: 'hello',
     p: [ 'a1', 'a2' ],
     f: function f() {
       this.p.forEach( item => {
         console.log(this.v + ' ' + item);
       }, this);
     }
   }
   
   o.f()
   // hello a1
   // hello a2
解决办法四:

也可使用bind永久绑定this

        var o = {
          v: 'hello',
          p: [ 'a1', 'a2' ],
          f: function f() {
            this.p.forEach(function (item){
              console.log(this.v + ' ' + item);
            }.bind(this));
          }
        }
        
        o.f()
        // hello a1
        // hello a2
        

三,特殊情况

1,'use strict'

avaScript 提供了严格模式,也可以硬性避免这种问题。严格模式下,如果函数内部的this指向顶层对象,就会报错。

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

此时,上栗中的this为window,这里就为未定义了!!!

2,函数被赋给另一个变量

只要函数被赋给另一个变量,this的指向就会变,变为新变量所在执行环境对象

var A = {
  name: '张三',
  describe: function () {
    return '姓名:'+ this.name;
  }
};

var name = '李四';
var f = A.describe;
f() // "姓名:李四"

此例中this为window

没写完呢。。。。。。。。。。。。。。。。。。。。


songjie4590
4 声望0 粉丝