当前位置: 首页 > news >正文

call、apply、bind的用法

call

函数的调用方式:

  1. 直接调用functionName()
  2. 使用 call 调用。functionName.call()

每一个人都会更喜欢第一种这种更简单的方式,然而,第2种才是 JavaScript 中函数的真正调用方式。
call是函数的原型Function.prototype上的方法,每一个函数都拥有。
在JS引擎中,调用一个函数的真正方式是调用函数的call方法。

函数的call方法: 语法:

fun.call(thisArg, arg1, arg2, ...)

call 调用一个函数,给该函数一个指定的 this 值 thisArg 和指定的参数 arg1, arg2, ...
call、apply 指定的参数会在 arguments 中顺序排列在原函数的参数后面。

使用 call 调用一个函数:

var obj = {
    name: 'Sam',
    age: 22,
}

function fn(){
    console.log(this)
}

fn.call(obj)    // 对象 obj {name: 'Sam',age: 22}
fn()            // 对象 window
复制代码

使用 call 调用函数与直接调用函数的区别:

  • 直接调用函数是JS的一个语法糖,引擎依然会调用call方法。只是,在调用call方法时,由于没有手动指定 this 值,JS引擎会自动隐式传入一个 this 值。
  • 使用call调用函数,必须手动指定 this 的值。手动传入的 this 必须是个对象,若传入的不是对象,JS引擎会自动转换成相应类型对象。这时,函数之中的 this 就是这个手动指定的对象。
  • 需要注意的是,在非严格模式下,当使用call调用函数时,若传入的 this 是 null 或 undefined,会默认指向 window 对象。

call()的应用

  1. 将伪数组转为真正的数组
var arr = Array.prototype.slice.call(fakeArray)

Array.prototype.slice.call({0: 'a',1: 'b',length: 2})
Array.prototype.slice.call(document.querySelectorAll('div'))  // querySelectorAll 通过遍历获得元素,静态对象。添加新的元素,length不会增加
Array.prototype.slice.call(arguments)
复制代码
  1. 实现对象继承
var constructor = function(name,age){
    this.name = name
    this.age = age
}
var obj = {}
constructor.call(obj,'sam',18)
console.log(obj)        // {name: sam, age: 18}
复制代码

apply

apply()的用法与call()基本一致,apply()使用时接受的参数是一个数组,而不是像call()那样的参数列表。其他方面,两者并无不同。

apply()的应用

  1. 将伪数组转为真正的数组 使用方法与call()一样。
    需要注意的是,无论call()还是apply(),被转化的伪数组都必须具有length属性和对应的数字键
  2. 找出数组中的最大值
var array = [1,2,3,4,5,6,7,8,9]
Math.max.apply(undefined, array)
复制代码
  1. 将数组中的空元素转换为 undefined
Array.apply(null,[1,,2])  // [1,undefined,2]
复制代码

bind

bind()给函数的 this 绑定一个指定的对象,返回一个一样的新函数。bind() 不仅能绑定 this 的指向,还能绑定原函数的参数。就是说,bind()的第二个参数之后的参数是会覆盖原函数的参数。

bind比call方法和apply方法更进一步的是,除了绑定this以外,还可以绑定原函数的参数。– JavaScript标准参考教程

var obj = {
    count: 1,
    add: function(){
        this.count += 1
    }
}

var count = 20

// 对象调用方法,this指向对象
obj.count     // 1
obj.add()     
obj.count    // 2

// 函数表达式调用方法,this 指向 window
var f = obj.add
f()
count        // 21

// bind 手动指定 bind
var fn = obj.add.bind(obj)
fn()      
obj.count     // 3
count         // 21
复制代码

简写原生方法

var log = console.log.call(console)
// var log = console.log.bind(console)
复制代码
// Fuction.prototype.call绑定 this 为 Array.prototype.slice
var slice = Function.prototype.call.bind(Array.prototype.slice);
// slice() === Array.prototype.slice.call()
复制代码

相关文章:

  • Perl的简单联网操作
  • [svc]NFS存储企业场景及nfs最佳实战探究
  • 1安装Linux
  • underscore源码剖析之整体架构
  • HDU-2087-剪花布条
  • 关于线性基的一丢丢理解
  • 基于阿里雲Oracle12cR2(Linux)實例靜默安装Cloud Control 13c 13.3
  • Spring Boot + thymeleaf 后台与页面(二)
  • vue学习系列(二)vue-cli
  • java8简短教程(持续更新含部分9,10,11)
  • Kali linux 2018安装后全屏乱码解决
  • SAP云平台对Kubernetes的支持
  • Centos6.5配置DNS
  • 机器学习你要了解的5件事
  • web开发中的跨域整理
  • 【笔记】你不知道的JS读书笔记——Promise
  • AHK 中 = 和 == 等比较运算符的用法
  • JAVA_NIO系列——Channel和Buffer详解
  • js操作时间(持续更新)
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • mysql innodb 索引使用指南
  • redis学习笔记(三):列表、集合、有序集合
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • Webpack 4 学习01(基础配置)
  • 程序员该如何有效的找工作?
  • 力扣(LeetCode)965
  • 一文看透浏览器架构
  • 在 Chrome DevTools 中调试 JavaScript 入门
  • media数据库操作,可以进行增删改查,实现回收站,隐私照片功能 SharedPreferences存储地址:
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • ​VRRP 虚拟路由冗余协议(华为)
  • #QT(串口助手-界面)
  • #我与Java虚拟机的故事#连载18:JAVA成长之路
  • $NOIp2018$劝退记
  • %check_box% in rails :coditions={:has_many , :through}
  • (2)STL算法之元素计数
  • (ZT)薛涌:谈贫说富
  • (附源码)spring boot基于小程序酒店疫情系统 毕业设计 091931
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (六)vue-router+UI组件库
  • (六)激光线扫描-三维重建
  • (免费领源码)Python#MySQL图书馆管理系统071718-计算机毕业设计项目选题推荐
  • (译) 函数式 JS #1:简介
  • (转)IIS6 ASP 0251超过响应缓冲区限制错误的解决方法
  • (转)jQuery 基础
  • (转载)hibernate缓存
  • .helper勒索病毒的最新威胁:如何恢复您的数据?
  • .net FrameWork简介,数组,枚举
  • .net 打包工具_pyinstaller打包的exe太大?你需要站在巨人的肩膀上-VC++才是王道
  • .net图片验证码生成、点击刷新及验证输入是否正确
  • /var/log/cvslog 太大
  • [ACTF2020 新生赛]Upload 1
  • [C语言]一维数组二维数组的大小
  • [docker] Docker容器服务更新与发现之consul
  • [Foreman]解决Unable to find internal system admin account