博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
apply、call、bind的学习总结
阅读量:6417 次
发布时间:2019-06-23

本文共 3025 字,大约阅读时间需要 10 分钟。

call

先来一个例子

const obj = {  name: 'xiaoming',  log: function(a) {    console.log(this.name, a);  }}obj.log(); // xiaoming undefined复制代码

call方法调用一个函数, 其具有一个指定的this值和分别地提供的参数

const callObj = {  name: 'call',}obj.log.call(callObj, 'callObj'); // call callObj复制代码

在非严格模式下,如果则指定为nullundefinedthis值会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象

window.name = 'window';obj.log.call(null, 'windowObj'); // window windowObj// call方法的实现Function.prototype.call = function(context) {  if (typeof this !== 'function') {    throw new TypeError('error');  }  context = context || window;  context.fn = this;  const result = context.fn(...[...arguments].slice(1));  delete context.fn;  return result;}复制代码

apply

apply方法的作用和call方法类似,区别就是call方法接受的是参数列表,而apply方法接受的是一个参数数组。

const applyObj = {  name: 'apply',}obj.log.apply(applyObj, ['applyObj']); // apply applyObj/*在非严格模式下,如果则指定为null和undefined的this值会自动指向全局对象(浏览器中就是window对象)同时值为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象*/window.name = 'window';obj.log.apply(null, ['applyObj']); // window windowObj// apply的实现Function.prototype.apply = function(context) {  if (typeof this !== 'function') {    throw new TypeError('error');  }  context = context || window;  context.fn = this;  const result = arguments[1] ? context.fn(...arguments[1]) : context.fn();  delete context.fn;  return result;};复制代码

bind

const bindObj = {  name: 'bind'}obj.log.bind(bindObj);/* 这里并不会打印bind,而是返回一个函数ƒ () {  console.log(this.name);}由此可见,bind()方法创建一个新的函数 */// 接着执行obj.log.bind(bindObj)(); // 打印 bind// 因此,当这个新函数被调用时其this置为提供的值复制代码

bind的另一个最简单的用法是使一个函数拥有预设的初始参数。这些参数(如果有的话)作为bind的第二个参数跟在this(或其他对象)后面,之后它们会被插入到目标函数的参数列表的开始位置,传递给绑定函数的参数会跟在它们的后面。

function list() {  return Array.prototype.slice.call(arguments);}console.log(list(1,2,3)); // [1, 2, 3]const presetList = list.bind(null, 0);console.log(presetList()); // [0]console.log(presetList(1, 2, 3)); // [0, 1, 2, 3, 4]复制代码

绑定函数适用于用new操作符去构造一个由目标函数创建的新的实例。当一个绑定函数是用来构建一个值的,原来提供的 this 就会被忽略。然而, 原先提供的那些参数仍然会被前置到构造函数调用的前面。

function Point(a, b) {  this.a = a;  this.b = b;}Point.prototype.toString = function() {  console.log(this.a + this.b);}const p1 = new Point(1,2);p1.toString(); // 3const obj = {}var P2 = Point.bind(obj, 1);const p3 = new P2(2);console.log(p3.toString()); // undefinedconsole.log(p3 instanceof P2); // trueconsole.log(p3 instanceof Point); // truenew Point(1, 2) instanceof P2; // true复制代码

bind的实现

Function.prototype.bind = function(context) {  if (typeof this !== 'function') {    throw new Error('Function.prototype.bind - what is trying to be bound is not callable');  }  const slice = Array.prototype.slice;  const args = slice.call(arguments, 1);  const self = this;  const F = function(){};  const fbound = function() {    return self.apply(this instanceof F ? this: context, args.concat(slice.call(arguments)));  }  if (this.prototype) {    F.prototype = this.prototype;  }  fbound.prototype = new F();  return fbound;}复制代码

结语

本人能力有限,难免出现错误内容,欢迎大佬们看到后,指出文章的错误以及给出更优质的答案

参考链接

转载于:https://juejin.im/post/5bc590b06fb9a05d07196cc2

你可能感兴趣的文章
程序员的常见“谎话”:对,这是一个已知 Bug
查看>>
如何侦查SQL执行状态
查看>>
CentOS 7 命令行如何连接无线网络
查看>>
Ubuntu 12.04上享用新版本Linux的功能
查看>>
logstash + grok 正则语法
查看>>
Zimbra开源版(v8.6)安装说明
查看>>
Android性能优化之TraceView和Lint使用详解
查看>>
基于pgrouting的路径规划之一
查看>>
LBS核心技术解析
查看>>
Fible Channel over Convergence Enhanced Ethernet talk about
查看>>
讨论:今日头条适配方案使用中出现的问题
查看>>
CSS3 3D翻转动画
查看>>
要命啦!Word中快速录入大全,内含快捷键小技巧,快来一起学习!
查看>>
javascript实现音频mp3播放
查看>>
html5-离线缓存
查看>>
linux系统安装完后的常见工作
查看>>
在Linux服务器、客户端中构建密钥对验证进行远程连接
查看>>
揪出MySQL磁盘消耗迅猛的真凶
查看>>
和“C”的再遇
查看>>
一键安装kubernetes 1.13.0 集群
查看>>