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

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

学到知识了就点个赞叭

相关推荐
_龙衣15 分钟前
将 swagger 接口导入 apifox 查看及调试
前端·javascript·css·vue.js·css3
struggle20251 小时前
continue通过我们的开源 IDE 扩展和模型、规则、提示、文档和其他构建块中心,创建、共享和使用自定义 AI 代码助手
javascript·ide·python·typescript·开源
x-cmd2 小时前
[250512] Node.js 24 发布:ClangCL 构建,升级 V8 引擎、集成 npm 11
前端·javascript·windows·npm·node.js
夏之小星星2 小时前
el-tree结合checkbox实现数据回显
前端·javascript·vue.js
为美好的生活献上中指4 小时前
java每日精进 5.11【WebSocket】
java·javascript·css·网络·sql·websocket·网络协议
拖孩5 小时前
【Nova UI】十五、打造组件库之滚动条组件(上):滚动条组件的起步与进阶
前端·javascript·css·vue.js·ui组件库
苹果电脑的鑫鑫5 小时前
element中表格文字剧中可以使用的属性
javascript·vue.js·elementui
一丝晨光6 小时前
数值溢出保护?数值溢出应该是多少?Swift如何让整数计算溢出不抛出异常?类型最大值和最小值?
java·javascript·c++·rust·go·c·swift
Wannaer6 小时前
从 Vue3 回望 Vue2:响应式的内核革命
前端·javascript·vue.js
懒羊羊我小弟7 小时前
手写符合Promise/A+规范的Promise类
前端·javascript