谈谈javascript里的this

js的this,被人讲了无数遍。这里我还是想在说一下自己的理解。
首先需要从函数调用开始讲起
es5中有三种函数调用的形式:

func(a1,a2);
obj.child.method(a1,a2);
func.call(context,a1,a2);

其实前两种调用方式都是call的简化版,

func.call(undefined,a1,a2);
obj.child.method.call(obj,a1,a2);

所以

function func(){
  console.log(this)
}
func()
等价于
function func(){
  console.log(this)
}
func.call(undefined);

因此,this应该指向undefined(node环境),但是在浏览器环境中,window会是默认传入的上下文context对象,所以打印结果为window。
那么,obj.child.method怎么确定this呢?

var obj = {
  foo:function(){
    console.log(this)
  }
}
obj.foo()
等价于
obj.foo.call(obj)

所以this就是你call一个函数时传入的context,这也就是this指向和声明位置无关,与调用位置有关。

  1. 默认绑定
    严格模式下this默认绑定到undefined,非严格模式下this默认绑定到window全局对象。
function hello(){
  var name = 'ke';
  console.log(this.name);
}
var name = cat;
hello(); //cat,调用的时候是hello的调用者是window
  1. 隐式绑定
    函数的调用位置会判断是否存在上下文对象(context),存在则将this绑定在上下文对象。
    一般写在某个对象内部包含一个指向函数的属性,通过这个属性间接引用函数,把this绑定到这个对象上。
function foo(){
  console.log(this.name)
}
var person = {
  name:'ke',
  foo:foo
}
person.foo()//ke

调用位置在person上下文,this.name 相当于person.name
但是也容易丢失绑定对象

function foo(){
  return function ke(){
    return this.name
  }
}
var person = {
  name:'ke',
  foo:foo
}
var name = 'cat'
console.log(person.foo()())

还有一种隐式就是回调函数。

var a ={
  num:10,
  add:add
}
var num =20;
function add(){
  return this.num + 10
}
function sum(fn){
  fn();
}
console.log(sum(add))

或者将定时器传入函数中,解决办法是var that = this或者箭头函数

  1. 显式绑定
    call apply
  2. new绑定

对象中的this,对象调用自己定义的方法时,this指向这个对象

var obj = {
  id:9,
  test:function(){
    return this.id;
  }
}
obj.test();

test在对象obj中,所以函数的运行环境就是obj所在上下文,所以this指向obj。

原型链中的this
getter setter里的this。

es6中引入箭头函数,此时this关键字指向当前函数的词法作用域,与声明位置有关,与调用位置无关。

你可能感兴趣的:(谈谈javascript里的this)