前端面试题 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,同时...可以将数组里的值分隔开来

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

学到知识了就点个赞叭

相关推荐
阿伟来咯~8 分钟前
记录学习react的一些内容
javascript·学习·react.js
吕彬-前端13 分钟前
使用vite+react+ts+Ant Design开发后台管理项目(五)
前端·javascript·react.js
学前端的小朱16 分钟前
Redux的简介及其在React中的应用
前端·javascript·react.js·redux·store
guai_guai_guai25 分钟前
uniapp
前端·javascript·vue.js·uni-app
也无晴也无风雨26 分钟前
在JS中, 0 == [0] 吗
开发语言·javascript
王哲晓2 小时前
第三十章 章节练习商品列表组件封装
前端·javascript·vue.js
理想不理想v2 小时前
‌Vue 3相比Vue 2的主要改进‌?
前端·javascript·vue.js·面试
酷酷的阿云2 小时前
不用ECharts!从0到1徒手撸一个Vue3柱状图
前端·javascript·vue.js
aPurpleBerry3 小时前
JS常用数组方法 reduce filter find forEach
javascript
ZL不懂前端3 小时前
Content Security Policy (CSP)
前端·javascript·面试