JavaScript this和bind、apply、call

news/2024/11/22 18:26:27/
  • this指向函数执行时的当前对象,它会随着执行环境的改变而改变。
  • this 是保留关键字,无法被修改
  • 任何函数本质上都是通过某个对象来调用的
  • 所有函数内部都有一个变量this,他的值是调用函数的当前对象

this指向

  • 在事件中,this 表示接收事件的HTML元素。
  • 普通函数中:谁调用了函数或者方法,那么这个函数或者对象中的this就指向谁
    • **fn()**为全局对象,在浏览器中是window,严格模式下为undefined
    • **p.fn()**:p,指向对象
    • **new fn()**:新创建的对象
    • **p.call(obj)**:obj
    • bind、call、apply 方法可以将 this 引用到任何对象。
  • 匿名函数:指向**window,**匿名函数的执行具有全局性
  • 箭头函数
    • 箭头函数中的this是在函数定义的时候就确定下来的,而不是在函数调用的时候确定的;
    • 箭头函数中的this指向恒定为父级作用域的执行上下文(父级作用域的this)
    • 箭头函数无法使用bind、call、apply方法改变this指向,因为其this值在函数定义的时候就被确定下来。

修改this指向函数

bind

  • 不会调用函数,但是可以改变函数内部this指向
  • 返回 由指定this 和指定实参的原函数拷贝,返回值中this永久改变
  • 使用addeventlinstener和attachevent解决不同版本的浏览器的适配问题
  • 修改attachevent内的回调函数使其this指向obj,与addeventlinstener默认的this指向obj统一

call、apply

  • 都是函数的方法,需要通过函数对象调用,函数也会执行
  • 调用call和apply会将第一个对象指定为第一个参数 ,此时这个对象会成为函数执行时this
  • call方法可以将实参在对象之后一次传递
  • apply需要将实参封装到一个数组中统一传递
  • call 和apply 都是用来改变函数的this的,改变向的this为第一个参数,原先传入的参数从第二位开始
  • 以函数形式调用时,this永远都是window
  • 以方法的形式调用时,this是调用方法的对象
  • 以构造函数的形式调用时,thi s是新创建的那个对象
  • 使用call和apply调用时,this是指定的那个对象
fun.call(this)//等同于 fun()
fun.call(obj)//此时指向obj
/* sayname内为一个返回此时this的函数,返回值为obj 
即 call改变了fun.sayname的this 
可以理解为一个修改当前语句this的方法 */
fun.sayname.call(obj)
fun.call(obj,a,b)//a,b类似其他函数传入的实参 即从第二位开始
fun.apply(obj,[a,b])//封装
// 给 Father 增加 name 和 age 属性
function Father(myName, myAge) {this.name = myName;this.age = myAge;
}function Son(myName, myAge) {// 通过这一步,将 father 里面的 this 修改为 Son 里面的 this;另外,给 Son 加上相应的参数,让 Son 自动拥有 Father 里的属性。最终实现继承//相当于在son身上调用了father方法Father.call(this, myName, myAge);
}const son1 = new Son('千古壹号', 28);
console.log(JSON.stringify(son1));上方代码中,通过 call() 方法,让 Son 继承了 Father 里面的 name 和 age 属性。
打印结果:
{"myName":"千古壹号","myAge":28}
const arr1 = [3, 7, 10, 8];// 下面这一行代码的目的,无需改变 this 指向,所以:第一个参数填 null,或者填 Math,或者填 this 都可以。严格模式中,不让填null。
const maxValue = Math.max.apply(Math, arr1); // 求数组 arr1 中元素的最大值
console.log(maxValue);const minValue = Math.min.apply(Math, arr1); // 求数组 arr1 中元素的最小值
console.log(minValue);

call appy bind的相同和不同

  • 相同:都可以改变函数内部的this指向。
  • 区别点:
    • call 和 apply 会调用函数,并且改变函数内部this指向。
    • call 和 apply 传递的参数不一样,call 传递参数arg1,arg2…形式, apply 必须数组形式
    • bind 不会调用函数,可以改变函数内部this指向。
    • 主要应用场景:
      • call 经常做继承。
      • apply 经常跟数组有关系,比如借助于数学对象实现数组最大值最小值。
      • bind 不调用函数,但是还想改变this指向,比如改变定时器内部的this指向。

http://www.ppmy.cn/news/709331.html

相关文章

python判断邮箱格式是否正确_python:校验邮箱格式

原博文 2019-09-06 16:48 − # coding:utf-8 import re def validateEmail(email): if re.match("^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$"... 0 1690 相关推荐 2019-12-23 17:18 − Python创建目录文件夹 Python对文件的操作还…

python邮箱格式验证_学会使用正则表达式——验证邮箱地址格式

为啥说我邮箱地址格式不对呢? 当您在一个网站或者客户端程序中,要注册一个新的用户时,网站或客户端程序可能会要求输入您的邮箱地址。也许您不想让网站或客户端程序知道您的邮箱地址,或者嫌输入麻烦,您会随便输入一段字符串,希望蒙混过关。可惜的是当您提交录入的注册信息…

微信号,手机号,邮箱验证格式

1、js验证 var wxreg /^[a-zA-Z]{1}[-_a-zA-Z0-9]{5,19}$/; var phonereg /^1[3456789]\d{9}$/;if(!wxreg.test(wx_no)){wx.showToast({title: 请输入正确的微信号,icon: none,duration: 1000})return false; }else if(!phonereg.test(phone)){wx.showToast({title: 请输入正…

android qq 邮箱格式,QQ邮箱格式怎么写

QQ邮箱格式怎么写 QQ邮箱现在最多可以拥有四个不同的邮箱格式,但是别人不管给你哪个账号发邮件,你都可以在同一个邮箱收到邮件。所以可以在不同场合,可以给对方不同的邮箱账号。那么QQ邮箱格式怎么写呢?怎么在合适的场合给别人一个…

公司企业邮箱账号格式怎么填?

公司企业邮箱是内部和外部商务往来主要的通讯工具,那使用的邮箱账号格式怎么填写呢?TOM企业邮箱格式常见以姓名全拼或数字组成的账号,下面教大家如何注册开通企业邮箱账号。 企业邮箱申请流程 企业邮箱需联系官网才能开通,区别于…

python判断邮箱格式是否正确_利用Python正则表达式模块,对邮箱帐号格式正确性校验(以QQ邮箱为例)...

非纯数字邮箱(@qq.com,@foxmail.com)?? a.1 您的邮箱帐号应该由a~z的英文字母(不区分大小写)开头; a.2 可由英文字母、0~9的数字(但不能使用全数字)、点、减号或下划线组成; a.3 长度为3~18个字符; a.4 不能以点、减号或下划线结尾,不能出现连续两个或两个以上…

字符串--day1--(leetcode344/leetcode541/剑指offer5)

文章目录 leetcode344.反转字符串基本思路介绍AC-code leetcode541. 反转字符串II基本思路介绍AC-code 剑指Offer 05.替换空格基本思路介绍AC-code 拓展 leetcode344.反转字符串 链接 基本思路介绍 实际上就是一个reverse函数就可以完成的,但是这边推荐手写一下&…

BACnet资料整理

BACnet stack 链接: link VS2019工程有几个编译错误,文件没有加入工程中 https://bacnet.sourceforge.net/ 使用该协议栈生成的几个工具 https://sourceforge.net/projects/bacnet/files/bacnet-tools/ BACnet stack BACnet基础 https://wenku.baidu.com/view/bd…