第14期 this

178 阅读2分钟

全局中的this

指向全局变量

函数中的this、

如果调用者被某一个对象所拥有,该函数内部的this指向该对象。

如果调用者为独立调用,严格模式下,this指向undefined,非严格模式下,this指向全局对象。

function fn() { 
  `'use strict'; 
  console.log(this) ; `
} 
fn();// 独立调用 但是fn是严格模式 所以this为undefined
window.fn();// 被window所拥有,this为window对象。
'use strict'; 
var a = 20; 
function foo () { 
  var a = 1; 
  var obj = { 
    a: 10, 
    c : this.a + 20 
  } 
  return obj.c; 
} 
console.log(window.foo()); // 此处foo内部的this指向window obj.c不属于函数调用 所以this指向foo的this 即window 结果输出40
console.log(foo());// 此处foo内部的this指向undefined 报错
function foo(){
  console.log(this.a);
}
function active(fn){
  fn();
}
var a = 20 ; 
var obj = { 
  a: 10, 
  getA: foo, 
  active: active 
}
active(obj.getA);// 20
obj.active(obj.getA);// 20
var n = 'window';
var object = {
  n:'object',
  getN:function(){
    return function(){
      return this.n;
    }
  }
}
console.log(object.getN()());// window

call/apply/bind 显式指定this

fn.call(obj,10,10);// 执行
fn.apply(obj,[10,10]);// 执行
let _fn = fn.bind(obj,10,10);// 不执行 返回一个函数 且this不可更改 函数参数不可更改

箭头函数的this

箭头函数不绑定this,箭头函数中的this相当于一个普通的变量。通过this进行寻值的方式跟普通变量的寻值方式相同,在作用域中逐级寻找,箭头函数中的this无法通过call、bind、apply进行直接修改,但是可以通过更改this所在的作用域的this的指向来达到更改this的指向,例如function closure(){()=>{//code }},在此例中,我们通过改变封包环境closure.bind(another)(),来改变箭头函数this的指向。

// 非严格模式
var name = 'window'

var person1 = {
  name: 'person1',
  show1: function () {
    console.log(this.name)
  },
  show2: () => console.log(this.name),
  show3: function () {
    return function () {
      console.log(this.name)
    }
  },
  show4: function () {
    return () => console.log(this.name)
  }
}
var person2 = { name: 'person2' }

person1.show1()
person1.show1.call(person2)

person1.show2()
person1.show2.call(person2)

person1.show3()()
person1.show3().call(person2)
person1.show3.call(person2)()

person1.show4()()
person1.show4().call(person2)
person1.show4.call(person2)()

构造函数的this

使用new操作符调用构造函数,会经历如下过程:

1、创建一个新的对象

2、将构造函数的作用域的this赋值给新的对象

3、执行构造函数的代码

4、返回一个新的对象

var name = 'window'

function Person (name) {
  this.name = name;
  this.show1 = function () {
    console.log(this.name)
  }
  this.show2 = () => console.log(this.name)
  this.show3 = function () {
    return function () {
      console.log(this.name)
    }
  }
  this.show4 = function () {
    return () => console.log(this.name)
  }
}

var personA = new Person('personA')
var personB = new Person('personB')

personA.show1()
personA.show1.call(personB)

personA.show2()
personA.show2.call(personB)

personA.show3()()
personA.show3().call(personB)
personA.show3.call(personB)()

personA.show4()()
personA.show4().call(personB)
personA.show4.call(personB)()

总结

非箭头函数:this总是指向调用该函数的对象。

箭头函数:作用域中逐级查找。(此处记住作用域分两种,一种是全局作用域,一种是函数作用域,对象不算是一个作用域)