搞懂javaScript里this指向

this指向

this指向什么

在浏览器中this的指向就是window
console.log(this) // window

但是不同的调用方式会有不一样的结果

function fun() {
    console.log(this)
}
// 方式一:直接调用
fun() // window

const obj = {
    name: 'qq',
    foo: fun
}
// 方法二:把函数放在一个对象内进行调用
obj.foo() // obj对象

// 方法三:使用call/apply进行调用
fun.call('aa') // String{'aa'}对象
  • this值的绑定跟其定义的位置没有关系
  • this值的绑定跟其调用的位置以及调用的方式有关系
  • this的值是在运行的时候进行绑定的

this的值是如何绑定的

默认绑定

当函数没有被绑定在一个对象上的时候进行调用时会进行默认绑定

function fun () {
    console.log(this)
}
fun() // window
function test1() {  
  console.log(this); // window  
  test2();  
}  

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

function test3() {  
  console.log(this); // window  
}  
test1();
function foo(func) {  
  func()  
}  

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

foo(bar);
function fun(foo){
    foo()
}
const obj = {
    name:'qq',
    foo: function(){
        console.log(this)
    }
}
fun(obj.foo) // window

隐式绑定

这是一种比较常见的绑定方式,就是函数的调用方式是通过一个对象发起的

必须在对象中的有一个属性进行引用了某个函数,正是这个引用使this的值绑定在了这个对象上
function fun() {
    console.log(this)
}
const obj = {
    name: 'qq',
    fun: fun
}
obj.fun() // obj对象
function fun() {
    console.log(this)
}
const obj1 = {
    name:'qq1',
    fun: fun
}
const obj2 = {
    name: 'qq2',
    obj: obj1
}
obj2.obj1.fun() // obj1对象

隐式丢失

function fun () {
    console.log(this)
}

const obj = {
    name: 'qq',
    fun: fun
}
const a = obj.fun
a() // window

此时会发生隐式丢失的问题,因为a在调用的时候没有绑定任何对象,也就没有形成隐式绑定,所以这个时候this的值是window

显式绑定

call、apply

通过call或apply绑定this对象

function fun(){
    console.log(this)
}
fun.call(window) // window
fun.call({name: "qq"}) // {name:"qq"}
fun.call(111) // Number对象,存放111

bind函数

方案一:我们可以自己手写一个辅助函数进行绑定this的值

function fun() {
    console.log(this)
}
function bind(func, obj) {
    return function() {
        return func.apply(obj,arguments)
    }
}
var obj = {
    name: 'qq'
}
var example = bind(fun, obj)
example() // bind对象

方案二: 使用 Function.prototype.bind

function fun () {
    console.log(this)
}
var obj = {
    name: 'qq'
}
var example = fun.bind(obj)

example() // obj对象

new绑定

javaScript中的函数可以当做一个类的构造函数来使用的,也就是可以使用new关键字

使用new关键字会执行以下操作:

  1. 创建一个全新的对象
  2. 这个对象会被执行Prototype连接
  3. 这个全新的对象会绑定到函数调用的this上(this的绑定)
  4. 如果函数没有返回其他对象,表达式会返回这个新对象
// 创建Person  
function Person(name) {  
  console.log(this); // Person {}  
  this.name = name; // Person {name: "why"}  
}

var p = new Person("why");  
console.log(p);

优先级

new绑定 > 显示绑定(bind)> 隐式绑定 > 默认绑定

箭头函数

ES6语法新增了一个箭头函数语法

箭头函数不进行this的绑定,而是根据外层作用域来决定this的值

// 不使用箭头函数
var obj = {
  data: [],
  getData: function() {
    var _this = this;
    setTimeout(function() {
      // 模拟获取到的数据
      var res = ["abc", "cba", "nba"];
      _this.data.push(...res);
    }, 1000);
  }
}

obj.getData();

下面可以在setTimeout中直接使用this了,因为箭头函数并不进行this的绑定,那么this的引用就会从上层作用域中找到对应的this

// 使用箭头函数
var obj = {
  data: [],
  getData: function() {
    setTimeout(() => {
      // 模拟获取到的数据
      var res = ["abc", "cba", "nba"];
      this.data.push(...res);
    }, 1000);
  }
}

obj.getData();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值