this

this

概述:

在 JavaScript 中,this 是指当前函数中正在执行上下文环境。

正常情况下的 this

默认指向调用函数的对象。

const person = {
  name: 'Tom',
  talk() {
    return this.name;
  },
};
person.talk(); //'Tom'

当函数在顶层作用域调用时,指向全局变量。

function print() {
  console.log(this);
}
print(); //Window    (浏览器中)

启用严格模式后,this 将默认指向 undefined

function print() {
  'use strict';
  console.log(this);
}
print(); //undefined

PS: 函数与方法之间没有明显区分,方法偏向于面向对象的说法。

构造函数中的 this

function Person(name) {
  this.name = name;
}
const person = new Person('Tom');
console.log(person.name); //'Tom'

通过 new关键字,this 指向新生成的实例。

箭头函数中的 this

class Obj {
  get() {
    return () => {
      return () => {
        return this;
      };
    };
  }
}
let obj = new Obj();
console.log(obj.get()()() === obj); //true

obj = {
  get: () => {
    return this;
  },
};
console.log(obj.get() === obj); //false
console.log(obj.get() === window); //true
var a = 100;
const fn1 = () => {
  console.log(this.a);
};
function fn2() {
  console.log(this.a);
}
const obj = { a: 1 };
fn1(); //100
fn2(); //100
fn1.apply(obj); //100
fn2.apply(obj); //1

箭头函数的 this ,指向函数定义时的执行上下文,即使用 callapplybind 也不改变。

call apply bind

  • callapplybind非箭头函数下都能改变函数内 this 的指向。
  • call 第二个参数开始都是函数执行的参数。
  • apply 第二个参数接受一个数组,数组内的元素依次为函数执行的参数。
  • bind 返回不立即执行的一个自定义函数,第二个参数开始都是原函数执行的参数,而自定义函数的传参将成为续bind参数后的原函数执行参数。
var a = 1,
  b = 2;
function print(c, d) {
  console.table(this.a, this.b, c, d);
}
print(3, 4);
// 1 2 3 4

print.call(
  {
    a: 10,
    b: 20,
  },
  30,
  40
);
//10 20 30 40

print.apply(
  {
    a: 100,
    b: 200,
  },
  [300, 400]
);
// 100 200 300 400

const fn = print.bind(
  {
    a: 1000,
    b: 2000,
  },
  3000
);
fn(4000);
//1000 2000 3000 4000

手写call

Function.prototype._call = function(ctx,...params){
  // 1.处理传参的可能出现的特殊情况
  if(ctx === null || ctx === undefined){
    ctx = window 
  }else if(!ctx instanceof Object){
    ctx = Object(ctx)
  }
  //给予唯一标识  避免对参数的原属性覆盖
  const temp = Symbol()
  ctx[temp] = this;
  // 执行函数并接收返回值
  const relt = ctx[temp](...params)
  // 回收
  delete ctx[temp]
  return relt
}
var a = 1 
function fn(b){
  console.log(this.a,b)
}
fn(2)     //1 2
const obj ={
  a: 10
}
fn._call(obj,3) //10 3

手写 apply

//与 call 同理
Function.prototype._apply = function(ctx,arr){
  if(ctx ===null || ctx ===undefined){
    ctx = window 
  }else if(!ctx instanceof Object){
    ctx = Object(ctx)
  }
  const temp = Symbol()
  ctx[temp] = this;
  const relt = ctx[temp](...arr)
  delete ctx[temp]
  return relt
}
var a = 1 
function fn(b,c,d){
  console.log(this.a,b,c,d)
}
fn(2,4,6)     //1 2 4 6
const obj ={
  a: 10
}
fn._apply(obj,[3,5,7]) //10 3 5 7

手写 bind

Function.prototype._bind = function(ctx,...params){
  if(ctx ===null || ctx ===undefined){
    ctx = window 
  }else if(!ctx instanceof Object){
    ctx = Object(ctx)
  }
  const _this = this
  // 使用闭包返回
  return function (...rest){
    const temp = Symbol()
    ctx[temp] = _this;
    const relt = ctx[temp](...params,...rest)
    delete ctx[temp]
    return relt
  }
}
var a = 1 
function fn(b,c,d){
  console.log(this.a,b,c,d)
}
fn(2,4,6)     //1 2 4 6
const obj ={
  a: 10
}
const newFn = fn._bind(obj,3)
newFn(5,7)   //10 3 5 7
posted @ 2022-08-09 10:32  --Odyssey--  阅读(30)  评论(0)    收藏  举报