首页 > 其他分享 >js面试(this指向)

js面试(this指向)

时间:2024-03-16 21:46:05浏览次数:19  
标签:console log 指向 bind js 面试 fun obj

一、全局下的this

浏览器环境指向window,Node环境指向Global

console.log(this);   // Window  

二、对象调用

谁调用指向谁

var obj = {
  num: 0,
  fun() {
    console.log(this); // {num: 0, fun: ƒ} 指向 obj 对象
  },
};

obj.fun();

三、独立调用

浏览器环境指向window,Node环境指向Global

function fun() {
  console.log(this); // Window
}
// 独立调用
fun();

var obj = {
  num: 0,
  fun() {
    function test() {
      console.log(this); // Window
    }
    // 独立调用
    test();
    // 立即执行函数也是独立调用
    (function fun() {
      console.log(this); // Window
    })();
  },
};

obj.fun();
var obj = {
  num: 0,
  fun() {
    function test() {
      console.log(this); // Window
    }
    // 形成闭包
    return test;
  },
};

// obj.fun()返回一个函数,然后直接调用
obj.fun()(); 
function foo() {
  console.log(this);
}

function bar(fn) {
  // 独立调用
  fn(); // window
}

var obj = {
  foo,
};

// 传递的是对foo函数的引用,但此时没有调用
bar(obj.foo);

四、new

class Person {
  constructor() {}
  fun() {
    console.log(this);
  }
}

const person = new Person();
person.fun();   // Person {}
function Fun() {
  console.log(this);
}

let obj = { name: "obj" };
// new 的优先级比bind要高
let fun_bind = Fun.bind(obj);
new fun_bind(); // Fun {}

下面这种情况虽然不会出现,但需要注意

class Person {
  constructor() {
    let obj = { name: "sun" };
    // 在构造函数中返回一个值,如果是引用数据类型会改变返回结果,如果是基本数据类型则不会改变
    return obj;
  }
  fun() {
    console.log(this);
  }
}

const person = new Person();
console.log(person);  // {name: 'sun'}

五、箭头函数

  1. 箭头函数没有自己的this指向,所以它会根据作用域链一层一层往外找。

    function fun() {
      return () => {
        console.log(this);
      };
    }
    
    var obj = {
      a: 1,
      fun,
    };
    
    // 这里obj.fun()返回了一个箭头函数,通过独立调用,指向的却不是 window ,所以独立调用对箭头函数无效
    obj.fun()();  // {a: 1, fun: ƒ}
    
    function fun() {
      return () => {
        console.log(this);
      };
    }
    
    var obj = {
      a: 1,
      fun,
    };
    
    // 这里尝试修改箭头函数的 this 指向,但无效。箭头函数都没有this指向,又怎么可能修改呢?
    fun().call(obj); // window
    
    const fun = () => {
      console.log(this);
    };
    
    // 尝试使用 new 来实例化,会直接报错,箭头函数不能作为构造函数使用
    new fun();  // Uncaught TypeError: fun is not a constructor
    

六、修改this指向

call、apply、bind

  1. 都可以修改this指向

  2. call、apply会立即执行,bind返回一个修改this执行后的函数

  3. call、bind传递函数参数为多个,apply传递数组

  4. 多次使用bind,只有第一次有效

    let obj = {};
    function fun(a, b) {
      console.log(this); 
      console.log(a, b);
    }
    
    fun.call(obj, 1, 2); // {} 指向 obj
    fun.apply(obj, [1, 2]); // {} 指向 obj
    fun.bind(obj)(1, 2); // {} 指向 obj
    
    fun.call(1, 1, 2); // Number {1}
    fun.apply("1", [1, 2]); // String {'1'}
    fun.bind(true)(1, 2); // Boolean {true}
    fun.call(Symbol(), 1, 2); // Symbol {Symbol(), description: undefined}
    fun.apply(BigInt(1), [1, 2]); // BigInt {1n}
    fun.bind(undefined)(1, 2); // window
    fun.call(null, 1, 2); // window
    
    fun.bind({ name: "第一个" }).bind({ name: "第二个" }, 3, 4)();  // {name: '第一个'}
    

七、补充

  1. 数组中forEach中传递的函数的this

    let obj = {};
    let arr = [1, 2, 3];
    arr.forEach(function () {
      console.log(this); // window
    });
    
    arr.forEach(function () {
      console.log(this); //  {} 指向 obj
    }, obj);
    
    arr.forEach(() => {
      console.log(this); // window
    });
    
    arr.forEach(() => {
      console.log(this); // window
    }, obj);
    

八、总结

  1. this绑定有4种
    • 默认绑定:window,独立调用也指向window
    • 隐式绑定:对象调用 obj.fun(),谁调用就指向谁
    • 显示绑定:call、apply、bind
    • new绑定:new Person()
  2. 优先级:new > 显示绑定 > 隐式绑定 > 默认绑定
  3. 箭头函数没有this指向,会通过作用域链往上找

标签:console,log,指向,bind,js,面试,fun,obj
From: https://www.cnblogs.com/finish/p/18077674

相关文章

  • 纯前端实现 PNG 图片压缩 | UPNG.js
    在线Demo体验地址→:https://demos.sugarat.top/pages/png-compress/前言最近在迭代自己的图床应用,由于使用时间的累计,存储空间占用越来越大了,在做Web应用的时候会随手拿tinypng压缩一下图片。想着给咱图床也加个压缩的功能,这样上传/访问也能省点......
  • JS实现之用户注册协议倒计时
    要求:按钮显示5秒倒计时,5秒前禁点,5秒后可以点击按钮运行结果:5秒前5秒后思路开启禁用按钮属性disabled获取按钮元素开启倒计时函数setInterval调用函数,函数里包括变量自减,使用DOM对象修改时间,关闭按钮禁用属性HTML代码:首先禁用按钮属性<textareaname=""id=""......
  • 分享一下自己总结的7万多字java面试笔记和一些面试视频,简历啥的,已大厂上岸
    分享一下自己总结的7万多字java面试笔记和一些面试视频,简历啥的,已大厂上岸总结的面试资料:面试资料SSMSSM搭建的版本有很多,例如有一个版本可以这么搭建,两个核心配置文件web.xml,applicationContext.xml。1.前端控制器DispatcherServlet2.过滤器CharacterEncodingFilter`......
  • 华为OD机试Js - 文件缓存系统
    文件缓存系统前言:本专栏将持续更新互联网大厂机试真题,并进行详细的分析与解答,包含完整的代码实现,希望可以帮助到正在努力的你。关于大厂机试流程、面经、面试指导等,如有任何疑问,欢迎联系我,wechat:steven_moda;email:[email protected];备注:CSDN。题目描述请设计一个文件缓......
  • 华为OD机试Js - 高效货运
    高效货运前言:本专栏将持续更新互联网大厂机试真题,并进行详细的分析与解答,包含完整的代码实现,希望可以帮助到正在努力的你。关于大厂机试流程、面经、面试指导等,如有任何疑问,欢迎联系我,wechat:steven_moda;email:[email protected];备注:CSDN。题目描述老李是货运公司承运人......
  • 面试中可能问到的几种树结构(二叉树,平衡二叉树,红黑树,B树和B+树)
    二叉树的概念二叉树是一种树形结构,其特点是每个结点至多只有两棵子树(即二叉树中不存在度大于2的结点),并且二叉树的子树有左右之分,其次序不能任意颠倒。平衡二叉树概念平衡二叉树,是二叉树的一种变形,左子树的深度和右子树的深度不能超过一。红黑树概念红黑树是一种自......
  • JS之对密文进行AES解密
    需求:用户ID和用户名不能在传输时同时明文出现解决方式:后端对用户ID和用户名进行加密,传输后前端解密显示 后端的加密方式为:1.密码转换为字节,先通过PBKDF2WithHmacSHA256,盐值salt123(转换为字节),迭代次数2048次,密钥长度128位,将密码处理成密钥。2.用AES/GCM/NoPadding的方式对载......
  • 面试官:小伙子,能聊明白JMM给你SSP!我:嘚吧嘚吧一万字,直接征服面试官!
    写在开头面试官:小伙子,JMM了解吗?我:JMM(JavaMemoryModel),Java内存模型呀,学过的!面试官:那能给我详细的聊一聊吗,越详细越好!我:嗯~,确定越详细越好?起码得说一万字,您有时间听完?面试官:你要是真能说一万字全是干货的话,我当场拍板要你,给你SSP!我:这可是您说的,瞧好吧!为了拿到一个SSP级别的......
  • Java基础面试题整理2024/3/13
    1、可以使用switch的数据类型Java5以前,switch(arg)表达式中,arg只能是byte、short、char、int。Java5之后引入了枚举类型,也可以是枚举类型。Java7开始引入了字符串类型。2、Java中的goto有什么作用goto是Java中的保留字,在目前版本的Java中没有使用。3、this与super的区......
  • 面试攻略:项目经理常见问题及标准答案一网打尽
    一、请介绍下你自己这是每家公司在面试时基本都会问的第一个问题,但如何在三分钟内用简洁的语言表达出你的个人特点、经验、优势是十分考验人的,而面试官会在你的介绍中寻找符合工作要求的关键词。可采用:“我是谁+相关经验+为何来应聘”这样的结构来回答。例如:面试官您好,我......