this(回顾)

文章详细阐述了JavaScript中this的概念和不同环境下的指向规则,包括全局作用域下指向window、函数调用时的指向、箭头函数的特殊性。同时,介绍了call、apply和bind方法用于改变this指向的用法及封装实现,并对比了它们的区别。此外,文中还通过示例解析了定时器和立即执行函数中this的指向问题。

概念

函数执行的主体(不是上下文):意思时谁把函数执行的,那么执行主体就是谁

使用情况

  1. 全局作用域下的this指向 window (非严格模式)
  2. 函数中的this:前面是谁,就指向谁(当前的作用域)
  3. 立即执行函数,定时器的this指向 window
  4. 构造函数的this,指向当前实例
  5. 箭头函数的this指向创建时的作用域
  6. bindcallapply 可以改变this指向

不同环境下的全局作用域

  1. 浏览器环境下,全局作用域指向 window,frames,this
  2. node环境下,指向 global
  3. 通用:globalThis

this题目

经典例题1

点前面是谁就指向谁

例题链接
扩展例题链接

var length = 10
function fn(){
  console.log(this.length)
}
var obj = {
  length:5,
  methods:function(fn){
    fn() //没有点,即没有调用关系,this指向window
    arguments[0]() //可理解为,argument.fn(),指向arguments
  }
}
obj.methods(fn,1)// 10  2

定时器的this指向window

例题链接

var x = 4;
var obj = {
  x: 3,
  bar: function () {
    var x = 2
    setTimeout(function () {
      var x = 1
      console.log(this.x)//4
    }, 1000)
  }
}
obj.bar()

箭头函数的this区别

例题
经典例题

call,apply,bind

call

定义:基于 Function.prototype.call 方法,改变this 指向
使用方法:fn.call(thisArg, arg1, arg2, …)
注意:参数1:若为 undefinednull,this指向 window ( 严格模式为undefined )

封装 call

Function.prototype.myCall1 = function (ctx) {
  ctx = ctx || window;
  ctx.fn = this;
  var args = [].slice.call(arguments,1);
  var res = eval("ctx.fn(" + args.join() + ")");
  delete ctx.fn;
  return res;
};
// es6
Function.prototype.myCall2 = function (ctx = globalThis, ...args) {//解构赋值 会把 null 赋值过来
  if (ctx === null) {
    ctx = globalThis;
  }
  ctx.fn = this;
  let res = eval(`ctx.fn(${args.join()})`);
  delete ctx.fn;
  return res;
};

apply

定义:改变this指向
使用方法:fu.apply(thisArg, [argsArray])
注意:参数2必须是数组或类数组

封装

Function.prototype.myApply = function (ctx) {
  ctx = ctx || window;
  ctx.fn = this;
  var args = [].slice.call(arguments,1);
  var res = eval("ctx.fn(" + args.join() + ")");
  delete ctx.fn;
  return res;
};
// es6
Function.prototype.Apply2 = function (ctx, ...args) {
  ctx = ctx || globalThis;
  return this.call(ctx, ...args);
};

bind

定义:改变this指向,生成一个新函数
使用方法:fn.bind(thisArg, arg1, arg2, …)
注意:bind是预处理this,不会让函数执行,返回新函数 ==》 柯里化函数
IE6~IE8不支持

封装 bind

Function.prototype.myBind = function (ctx) {
  ctx = ctx || window;
  var self = this;
  var args = [].slice.call(arguments, 1)
  return function () {
    var temp = [].slice.call(arguments,0)
    args=args.concat(temp); 
    self.apply(ctx, args);
  };
};
// es6
Function.prototype.myBind = function (context, ...params) {
  return (...res) => this.apply(context, [...params, ...res]);
};

区别

  1. 参数:apply的参数2传入数组或类数组
  2. 函数执行:bind不执行函数,而是生成一个新函数
  3. 兼容性:bind在IE6~8不支持
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柳晓黑胡椒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值