js中的this指向问题

首先this提供了一种更优雅的方式来隐式“传递”一个对象引用,因此可以将API设计得更加简洁并且易于复用。刚刚入门javascript的时候,就不停的听到this多么多么重要balala。。。,最开始觉得也没什么,无非是某些特殊的情况下this指向会混乱, 提前var that=this就好了嘛,但是随着对于js的不断深入理解,this的重要性就会不断凸现出来,也正是由于this 关键字有能力具备多重含义,带来灵活性的同时,也为初学者带来不少困惑,本文就以面试中常见的一些this指向性的面试题为起点,来深入了解下this

一. what is this?

Javascript中的this是当前执行上下文对象的一个属性,在创建执行上下文时生成,在执行上下文中不可改变。但会随着不同执行上下文的不断变化而改变,这也是问题所在。

以 “use strict”; 指定的JavaScript严格模式下,在this没有指向的时候,就赋值为undefined。 在非严格模式下,this在没有具体的指向的时候会指向全局对象,即浏览器运行时的window对象。

非严格模式会因为JavaScript的作用域的和执行上下文的变化导致一些难以排查的问题,因此目前JavaScript从5.1开始逐渐向严格模式倾斜。

JavaScript中的this取决于函数的调用环境和调用方式,后者比前者更重要。同时,this的指向在执行上下文创建的时候是决定不了的,在调用过程中才会决定,通俗点,谁调用,指向谁。

二.JavaScript this 确定规则(从前到后优先级逐渐降低)

首先先讲道理

  • 如果使用了new 关键字,this 就是新创建的这个对象;
  • 如果使用了函数的abc方法(apply,bind,call),this即为这个明确指定的对象。
  • 如果函数使用了明确对象来调用(对象方法),this为这个调用对象。
  • 默认,严格模式this为undefined,非严格模式为全局对象(ES6的箭头函数会默认使用外层作用域的this)

三.随便来点简单的

1.function test(){
  var name='zhangsan'
  console.log(this)//window
  console.log(this.name)//undefined
}
test();
复制代码

首先呢,test函数直接被window调用,所以this指向为window对象,test()等价于window.test()

2.

var obj={
    name:"张三",
    showName:function(){
    var name='李四'
    console.log(this.name)
    }

}
obj.showName()//张三

复制代码

此时,我们通过obj这个对象来调用函数,按照谁调用指向谁这个道理,this此时的指向就是obj

var name="赵五"
3.var obj={
    name:"张三",
    showName:function(){
        var name='李四'
    console.log(this.name)//undefined
    }

}
var fn=obj.showName
fn()//赵五

(obj.showName=obj.showName)()//赵五
复制代码

接下来皮一下,此时this又被指向回了window,原因是声明变量的时候,函数并没有被上一级对象调用,所以this指向没有被确定(fn相当于该函数的指针),当我们调用fn()的时候,此时仍然是window在调用该函数,所以this又重新指向了window。

(obj.showName=obj.showName)() 根据=从右向左进行赋值 把右边的obj.showName赋值到左边的obj.showName 等价于把右边的匿名函数重新赋值给脸obj.showName 此时 obj.showName整体相当于一个全局变量,这个变量是一个函数性质的变量,再用()调用这个函数时 this指向的是全局变量中的name 输出的是赵五。可以这么理解:var fn=obj.showName;fn() 输出的就是赵五 这个和上面的区别是使用了=号赋值(此时会改变this的指向)操作,上面那个没有进行=号赋值,后面直接进行调用的obj.showName这个匿名函数。

4.var obj={
    name:"张三",
    item1:{
    name:"李四"
    showName:function(){
    console.log(this.name)//李四
        }    
    }
   

}
obj.item1.showName()
复制代码

ok,当有多个对象嵌套的时候,尽管外层obj对象是调用的发起者,但是 this始终会指向直接调用它的上一级对象,也就是item1

//做道题吧~

this.name = '李四';    
var module = {
  name: '张三',
  getName: function() { return this.name; }
};

module.getName(); // 张三

var retrieveName = module.getName;
retrieveName();  // 李四

var boundGetName = retrieveName.bind(module);
boundGetName(); // 张三

复制代码

用一道题把上面的知识点都覆盖下,答案很简单谁调用,指向谁,boundGetName相当于module.getName的指针,而我们通过bind方法将该函数关联回了module对象,所以boundGetName函数调用时,this会指向module,最后我们把稍后会为大家讲一下函数的a,b,c(apply,bind,call)方法对于this指向的改变

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值