😁深入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);
相关推荐
Python私教11 分钟前
如意Agent日志系统重构:从 print() 大海捞针到结构化可观测性栈
java·前端·重构
We་ct30 分钟前
LeetCode 97. 交错字符串:动态规划详解
前端·算法·leetcode·typescript·动态规划
Chengbei1139 分钟前
轻量化 Web 安全日志分析神器 星川智盾日志威胁检测、地理溯源、MITRE ATT&CK 映射,支持 Windows/macOS/Linux
前端·人工智能·安全·web安全·macos·系统安全·安全架构
风流 少年41 分钟前
Python Web框架:FastAPI
前端·python·fastapi
GISer_Jing1 小时前
AI时代面试新常态——从“会用工具”到“深挖原理”的跨越
前端·人工智能·ai编程
IT_陈寒1 小时前
React的useEffect把我坑惨了,这些闭包陷阱真要命
前端·人工智能·后端
前端之虎陈随易1 小时前
有生之年系列,Nodejs进程管理pm2 v7.0发布
前端·typescript·npm·node.js
ayqy贾杰1 小时前
Cursor SDK发布!开发者可直接搬走其内核
前端·vue.js·面试
椰猫子1 小时前
SpringMVC(SpringMVC简介、请求与响应(请求映射路径、请求参数、日期类型参数传递、响应json数据))
java·前端·数据库