前端面试题 this指向问题

相信很多人在撸代码的时候,涉及到this总会出现一些问题,无法得到我们想要的值。大多数时候是我们没有弄清楚this的指向到底是什么,所以在某些情况下,this得到的不是我们想要的值。最近学习了一下函数中this指向的问题,在此分享出来也方便自己日后巩固学习。

谁调用就指向谁

一般情况下,谁调用,就指向谁,没有任何对象调用时,默认指向window对象

举个栗子 复制代码
function fn(){
      console.log('hello world');
      console.log(this);
    }
 fn()

输出

函数fn相当于挂在window上,调用fn()等同于调用window.fn(),可以看作fn()是被window调用,因此this指向window
扩展:self在函数中同样返回window,self是window的另一种写法

举个栗子 复制代码
 function fn(){
      console.log(this);
    }
 fn()
 console.log(self);

输出

在这4种情况下

1. 全局作用域或者普通函数中this指向全局对象window(注意:定时器里面的this指向window)
举个栗子 复制代码
console.log(this);
    function fn(){
      console.log(this);
    }
    fn();
    setTimeout(function(){
      console.log(this);
    },1000)

输出

2. 对象的方法调用中,谁调用,this指向谁
举个栗子 复制代码
var obj = {
      say:function(){
        console.log(this);
      }
    }
    obj.say()

输出

3. 事件处理程序中this:指向被操作的元素对象,也有可能指向window
举个栗子 复制代码
 <button>按钮</button>
  <script>
    var btn = document.querySelector('button')
    btn.onclick = function(){
      console.log(this);
      fn()
    }
    function fn(){
      console.log(this);
    }
  </script>

输出

4.构造函数中this指向构造函数的实例
举个栗子 复制代码
 function Person(name, age) {
      this.name = name;
      this.age = age;
      this.show = function () {
        console.log(this);
      }
    }
    // 利用构造函数Person创建了两个实例化对象
    var p1 = new Person('cc', 12)
    var p2 = new Person('ddd', 14)
    p1.show()
    p2.show()

输出

小结

  1. 全局作用域下指向window,定时器指向window
  2. 对象中,谁调用就指向谁
  3. 事件处理程序中,指向事件处理程序绑定的元素

改变this指向方法(函数的标准调用)

call()

  • 语法:fn.call(this指向,函数参数)
  • 第一个参数是this指向,第二个参数是传参
  • 立即执行
javascript 复制代码
function fn(obj){
      console.log(this);
      console.log(obj);
    }
    fn.call(this,'aaa')

apply()

  • 语法:fn.apply(this指向,[函数参数])
  • 第一个参数是this指向,第二个参数必须数组
  • 立即执行
arduino 复制代码
function fn(obj){
      console.log(this);
      console.log(obj);
    }
    fn.apply(this,['aaa'])

bind()

  • 语法:fn.bind(this指向,函数参数)(函数参数)
  • 第一个参数是this指向,第二个参数开始都是函数的参数
  • 不是立即调用,需要再加()调用
  • bind()可以在方法后面直接调用
javascript 复制代码
function fn(obj){
      console.log(this);
      console.log(obj);
    }
    fn.bind(this,'aaa')()

扩展:

  • 接收多个实参可以用伪数组arguments
  • 在es6语法中,接收实参可以用...FnName,同时...可以将数组里的值分隔开来

好啦,今天的知识就分享到这里啦。欢迎大家在评论里指点讨论

学到知识了就点个赞叭

相关推荐
来恩100325 分钟前
jQuery选择器
前端·javascript·jquery
前端繁华如梦27 分钟前
树上挂苹果还是挂玻璃球?Three.js 程序化果实的完整实现指南
前端·javascript
CDwenhuohuo1 小时前
优惠券组件直接用 uview plus
前端·javascript·vue.js
川冰ICE2 小时前
TypeScript装饰器与元编程实战
前端·javascript·typescript
AI砖家2 小时前
Vue3组件传参大全,各种传参方式的对比
前端·javascript·vue.js
希望永不加班2 小时前
var局部变量类型推断的利弊
java·服务器·前端·javascript·html
threelab2 小时前
Three.js 3D 地图可视化 | 三维可视化 / AI 提示词
前端·javascript·人工智能·3d·着色器
失眠的咕噜3 小时前
PDA 安卓设备上传多张图片
android·前端·javascript
掰头战士3 小时前
深入了解JS原型及原型继承链机制
javascript
一只叁木Meow3 小时前
电商 SKU 选择器:用算法实现优雅的用户交互
前端·javascript·算法