😁深入JS(二): 一文让你完全了解This作用与指向

一、 This作用

This关键字给予了访问当前上下文的能力

  • 通过this关键字,函数可以访问当前上下文对象的属性和方法

函数中的This

  • 函数为一个特殊的对象,每次调用将函数内容展开至当前上下文
js 复制代码
  var name = "window";
      var person1 = {
        name: "person1",
        foo1: function () {
          console.log(this.name);
        },
      };
      person1.foo1();//person1

二、 this的指向

默认绑定

  • 默认绑定:当一个函数独立调用,不带任何修饰符的时候

函数为一个特殊的对象,每次调用将函数内容展开至当前上下文,因此可类比为window.foo()

js 复制代码
function foo(){//foo独立调用
  console.log(this);//this指代window(全局)
}
foo();

隐式绑定

  • 隐式绑定:当函数的引用有上下文对象时(当函数被某个对象所拥有时)

函数为一个特殊的对象,每次调用将函数内容展开至当前上下文,因此可类比为obj.foo(),指向当前上下文

js 复制代码
var obj = {
  a:1,
  foo:foo//引用foo
}
function foo(){
  console.log(this.a)
}
obj.foo()//1

显式绑定

  • call() apply() bind() 显示的将函数的this绑定到一个对象上
js 复制代码
var obj = {
  a:1
}
function foo(){
  console.log(this.a)
}
foo.call(obj)//1

new绑定

  • new绑定:this指向创建出来的实例对象
js 复制代码
function Person(){
  this.name = '小李'
}
let obj = new Person()//{name:小李}

至于为什么可以去看new函数的实现

其他This绑定

  1. 事件处理程序(addEventListener)中的 this
  • 当一个函数作为事件处理程序被调用时,this 通常指向触发事件的元素。
  1. 箭头函数中的 this
  • 箭头函数不会绑定自己的 this,而是继承自外围函数的作用域中的 this
  1. 定时器(setTimeout,setinterval)的 this
  • this 通常指向window

三、箭头函数的This

箭头函数没有this

为了消除函数的二义性(构造函数直接调用)

所以箭头函数this指向外层上下文,不能创建属性

箭头函数没有 this。如果访问 this,则会从外部获取。

js 复制代码
 let name = "window";
      const obj = {
        name: "obj",
        sayHello: () => {
          console.log(this.name);//window
        },
      };
      obj.sayHello();

四、new 操作符的底层原理

new 操作符的实际行为可通过以下步骤模拟:

  1. 创建空对象 obj
  2. 将构造函数 this 绑定到 obj
  3. 执行构造函数代码
  4. 设置 obj.__proto__ 指向构造函数原型
  5. 返回 obj(除非构造函数返回引用类型)
js 复制代码
function _new(fn, ...args) {
  let obj = {};
  obj.__proto__ = fn.prototype;
  fn.apply(obj, args);
  return obj;
}

五、手写 call 方法实现显式绑定

利用隐式绑定实现

js 复制代码
 Function.prototype._call = function(obj, ...arr) {
   obj.fn = this
   obj.fn(...arr)   //隐式绑定
 }
Function.prototype._call=function(newThis,...arr){
    newThis=newThis||window
    let fn=Symbol()
    newThis[fn]=this
    Object.defineProperty(newThis, fn, { enumerable: false, });
    let ans=newThis[fn](...arr)
    delete newThis[fn]
    return ans
}

let arr = [1];
function fn() {
  console.log(this == arr);
}
fn._call(arr);
相关推荐
深念Y11 分钟前
我明白为什么B站没法在浏览器开直播了——Windows Chrome推流踩坑全记录
前端·chrome·webrtc·浏览器·srs·直播·flv
zhangxingchao22 分钟前
AI应用开发七:可以替代 RAG 的技术
前端·人工智能·后端
Sun@happy37 分钟前
现代 Web 前端渗透——基础篇(1)
前端·web安全
希冀1231 小时前
【CSS学习第十一篇】
前端·css·学习
隔窗听雨眠1 小时前
doctype、charset、meta如何控制整个渲染流水线
java·服务器·前端
kyriewen1 小时前
写组件文档写到吐?我用AI自动生成Storybook,同事以后直接抄
前端·javascript·面试
excel1 小时前
🧠 Prisma 表名大写 vs SQL 导出小写问题深度解析(附踩坑与解决方案)
前端·后端
周淳APP2 小时前
【前端工程化原理通识:从源头到运行时的理论阐述】
前端·编译·打包·前端工程化
五点六六六2 小时前
你敢信这是非Native页面写出来的渐变效果吗🌝(底层原理解析
前端·javascript·面试
tedcloud1232 小时前
TradingAgents部署教程:打造AI量化分析工作流
服务器·前端·人工智能·系统架构·edge