😁深入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);
相关推荐
悟能不能悟1 小时前
js闭包问题
开发语言·前端·javascript
秋秋_瑶瑶1 小时前
vue-amap组件呈现的效果图如何截图
前端·javascript·vue-amap
gnip3 小时前
js上下文
前端·javascript
中草药z3 小时前
【Stream API】高效简化集合处理
java·前端·javascript·stream·parallelstream·并行流
不知名raver(学python版)3 小时前
npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR!
前端·npm·node.js
醉方休3 小时前
React中使用DDD(领域驱动设计)
前端·react.js·前端框架
excel3 小时前
📖 小说网站的预导航实战:link 预加载 + fetch + 前进后退全支持
前端
学习3人组3 小时前
React 样式隔离核心方法和最佳实践
前端·react.js·前端框架
世伟爱吗喽3 小时前
threejs入门学习日记
前端·javascript·three.js