js中this总结

this指向问题

this 是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调用时的各种条件。this 的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式

全局函数(默认绑定)

全局函数的this,在严格模式下指向undefined,非严格模式下指向window

function foo() { console.log(this) }  foo() // window

'use strict'

function foo() { console.log(this) } foo() // undefined

对象方法(隐式绑定)

作为对象的方法存在的函数,谁调用它,this就指向谁。

function foo() { 
 console.log( this.a );
}
var obj2 = { 
 a: 42,
 foo: foo 
};

obj2.foo() // 42

对象属性引用链中只有最顶层或者说最后一层会影响调用位置,举例来说:

function foo() {
 console.log( this.a );
}
var obj2 = { 
 a: 42,
 foo: foo 
};
var obj1 = { 
 a: 2,
 obj2: obj2 
};
obj1.obj2.foo(); // 42

对象方法重新赋值为变量,要时刻注意是谁调用了函数:

function foo() { 
 console.log( this.a );
}
var obj = { 
 a: 2,
 foo: foo 
};
var bar = obj.foo; // 函数别名!
var a = "global"; // a 是全局对象的属性
bar(); // "global"

显式绑定

call

 function maile() {
    console.log(this.age)
  }
  var obj = {
    age: 18
  }

  maile.call(obj) // 18

apply

function maile(a) {
  
    console.log(this.age, a)
  }
  var obj = {
    age: 18
  }

  maile.apply(obj, [1]) // 18 1

bind

bind函数调用的参数就是this,返回的还是一个函数。

function maile() {
    console.log(this.age)
  }
  var obj = {
    age: 18
  }
  maile.bind(obj)() // 18

如果你把 null 或者 undefined 作为 this 的绑定对象传入 call、apply 或者 bind,这些值在调用时会被忽略,实际应用的是默认绑定规则。

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

然而,总是使用 null 来忽略 this 绑定可能产生一些副作用。如果某个函数确实使用了this(比如第三方库中的一个函数),那默认绑定规则会把 this 绑定到全局对象(在浏览器中这个对象是window),这将导致不可预计的后果(比如修改全局对象)。既然我们希望this是空,使用下面的方式会比较安全些:

function foo(a,b) {
 console.log( "a:" + a + ", b:" + b );
}
// 我们的 DMZ 空对象
var arr = Object.create( null );
// 把数组展开成参数
foo.apply( arr, [2, 3] ); // a:2, b:3

构造函数(new 绑定)

使用 new 来调用函数,或者说发生构造函数调用时,会自动执行下面的操作。创建(或者说构造)一个全新的对象。这个新对象会被执行 [[ 原型 ]] 连接。这个新对象会绑定到函数调用的 this。如果函数没有返回其他对象,那么 new 表达式中的函数调用会自动返回这个新对象。

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

箭头函数

箭头函数并不是使用 function 关键字定义的,而是使用被称为“胖箭头”的操作符 => 定义的。箭头函数不使用 this 的四种标准规则,而是根据外层(函数或者全局)作用域来决定 this。

var a = 2
var obj = {
  a: 1,
  foo: () => {
    console.log(this.a) 
  }
}
obj.foo() // 2

间接引用

function foo() { 
 console.log( this.a );
}
var a = 2; 
var o = { a: 3, foo: foo }; 
var p = { a: 4 };
o.foo(); // 3
(p.foo = o.foo)(); // 2

p.foo = o.foo 的返回值是目标函数的引用,因此调用的是foo函数,不是o或者p对象中的函数。

优先级

默认绑定是最低的,显式绑定优先级更高,new 绑定比隐式绑定优先级高

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值