分享一个基础面试题---手写call

分享一个基础面试题---手写call

  • 手写call笔记
    • 第一步
    • 第二步
    • 第三步

手写call笔记

call():在使用一个指定的this值和若干个指定的参数值的前提下调用某个函数或方法。

let foo = {value:1
};
function bar(){console.log(this.value);
}
bar.call(foo);//1

注意两点:

  1. call改变了this的指向,指向到foo;
  2. bar 函数执行了;

第一步

上述方式等同于:

let foo = {value:1;bar:function(){console.log(this.value)}
};
foo.bar();//1

这个时候this就指向了foo,但是这样却给foo对象本身添加了一个属性,所以我们用delete再删除它即可。
所以我们模拟的步骤可以分为:

  1. 将函数设为对象的属性;
  2. 执行该函数;
  3. 删除该函数;

以上个例子为例,就是:

//第一步
//fn 是对象的属性名,反正最后也要删除它,所以起什么名字都可以。
foo.fn = bar
//第二步
foo.fn()
//第三步
delete foo.fn

根据上述思路,提供一版:

//第一版
//将foo作为context参数传递
Function.prototype.call2 = function(context){//首先要获取调用call的函数,用this可以获取//将函数设为对象的属性context.fn = this;//执行该函数context.fn();//删除该函数delete context.fn;
}

第二步

call除了可以指定this,还可以指定参数

var foo = {value:1
};
function bar(name,age){console.log(name);console.log(age);console.log(this.value);
}
bar.call(foo,'ken',18);

可以从Arguments对象中取值,取出第二个到最后一个参数,然后放到一个数组里。
上述代码的Arguments中取第二个到最后一个参数。

//以上个例子为例,此时的arguments为:
// arguments = {
//		0:foo,
//		1:'ken',
//		2:18,
//		length:3
//}
//因为arguments是类数组对象,所以可以用for循环
var args = [];
for(var i = 1,len = arguments.length;i<len;i++){args.push('arguments['+i+']');
}
//执行后args 为["arguments[1]","arguments[2]","arguments[3]"]

接下来使用eval拼接成一个函数

eval('context.fn('+args+')')

考虑到目前大部分浏览器在console中限制eval的执行,也可以使用rest
此处代码为:

//第二版
Function.prototype.call2 = function(context){context.fn = this;let arg = [...arguments].slice(1);context.fn(...arg);delete context.fn;
}
//测试一下
var foo = {value:1
};
function bar(name,age){console.log(name);console.log(age);console.log(this.value);
}
bar.call2(foo,'ken',18)
//ken
//18
//1

第三步

  1. this参数可以传null,当为null的时候,视为指向window
    举个例子:
var value = 1;
function bar(){console.log(this.value);
}
bar.call(null);//1
  1. 针对函数,可以实现返回值
var obj = {value:1
};
function bar(name,age){return{value:this.value,name:name,age:age}
}
console.log(bar.call(obj,'ken',18));
//Object{
//		value:1,
//		name:'ken',
//		age:18
//}

第三版:

Function.prototype.call3=function(context){//1.this为null,也可以写为=>context ?? window 或者 context=context??windowvar context = context || window;context.fn = this;let arg = [...arguments].slice(1)let result = context.fn(...arg)delete context.fn//2.有返回值return result
}
//测试一下
var value = 2;
var obj = {value:1
}
function bar(name,age){console.log(this.value);return{value:this.value,name:name,age:age}
}
bar.call3(null);//2
console.log(bar.call3(obj,'ken',18));//1
//Object{
//		value:1,
//		name:'ken',
//		age:18
//}

这边给出的简化写法:

Function.prototype.call3 = function(context,..args){//判断是否是undefined和nullif (typeof context === 'undefined' || context === null){context = window}//每个从Symbol()返回的symbol值都是唯一的let fnSymbol = Symbol()context[fnSymbol] = this//入参...args === [...arguments].slice(1);let fn = context[fnSymbol](...args)//删除目的是不污染原来数据delete context[fnSymbol]return fn
}

可能会有新手宝宝们看完觉得还是很晦涩,可以动手写一遍试试,不行再多写两遍,好记性不如烂键盘,脑子再快也不如肌肉记忆哈哈哈~
当然也可以留言讨论啦~
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/204671.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android音量调节参考一

基于android 9平台分析。 在Android系统中&#xff0c;默认的设备(phone等)音量都是分开控制的&#xff0c;这些包括媒体、铃声、闹铃、蓝牙、通话通过音频流来区别不同的音量类型。每种流类型都定义最大音量、最小音量及默认音量&#xff0c;Android 9定了了11中音频流类型&am…

点评项目——商户查询缓存

2023.12.7 redis实现商户查询缓存 在企业开发中&#xff0c;用户的访问量动辄成百上千万&#xff0c;如果没有缓存机制&#xff0c;数据库将承受很大的压力。本章我们使用redis来实现商户查询缓存。 原来的操作是根据商铺id直接从数据库查询商铺信息&#xff0c;为了防止频繁地…

python中时间戳与时间字符的相互转换

1.获取时间的方法 使用的是time模块 import time time1 time.time() # time1: 1701934920.676534 timestruct time.localtime(time1) # timestruct: time.struct_time(tm_year2023, tm_mon12, tm_mday7, tm_hour15, tm_min42, tm_sec0, tm_wday3, tm_yday341, tm_isdst0)2.…

Apache Hive(部署+SQL+FineBI构建展示)

Hive架构 Hive部署 VMware虚拟机部署 一、在node1节点安装mysql数据库 二、配置Hadoop 三、下载 解压Hive 四、提供mysql Driver驱动 五、配置Hive 六、初始化元数据库 七、启动Hive(Hadoop用户) chown -R hadoop:hadoop apache-hive-3.1.3-bin hive 阿里云部…

【STM32单片机】简易电子琴设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用STM32F103C8T6单片机控制器&#xff0c;使用数码管模块、矩阵按键、无源蜂鸣器等。 主要功能&#xff1a; 系统运行后&#xff0c;蜂鸣器播放一首音乐&#xff0c;进入电子琴模式&#xff0c;…

无公网IP环境Windows系统使用VNC远程连接Deepin桌面

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;…

MySQL Connector/J 数据库连接 URL的语法

详情请参考&#xff1a;https://dev.mysql.com/doc/connector-j/en/connector-j-reference-jdbc-url-format.html jdbc:mysql:是用于普通的、基本的故障转移连接使用&#xff1a; jdbc:mysql://[host][,failoverhost...][:port]/[database][?propertyName1][propertyValue1]…

联想范建平:联想混合AI架构具备两大明显优势

12月7日&#xff0c;首届AI PC创新论坛在北京联想集团总部举办。联想集团副总裁、联想研究院人工智能实验室负责人范建平表示&#xff0c;为提供真正可信、个性化的AI专属服务&#xff0c;联想提出了混合智能&#xff08;Hybrid AI&#xff09;概念&#xff0c;并已经显现出更强…

thinkphp 多表连接 子查询 group by 分组以最新的一条数据为组

用这个 $subQuery Db::name(wms_orderitems)->distinct(true)->field(kw_id,orders_id,product_id)->order(items_id desc)->buildSql();$list Db::name(wms_orders)->alias(order)->join($subQuery. item,item.orders_idorder.orders_id)->field(order…

【AntDB 数据库】国产分布式数据库发展趋势与难点

引言&#xff1a; 日前&#xff0c;为更好地满足亚信科技客户对于数据管理的需求&#xff0c;提高通用型数据库的产品服务能力与业务拓展能力&#xff0c;亚信科技分布式数据库AntDB发布V7.0版本产品&#xff0c;助力运营商核心系统实现全方位的自主可控与业务系统的平稳上线。…

搭建部署Hadoop2.x和3.x的区别

文章目录 2.x 和 3.x 的区别Java最小支持版本常用的端口号配置文件Classpath隔离NodeManager重连 进入官网自行查阅 2.x 和 3.x 的区别 Java最小支持版本 Hadoop 2.x&#xff1a;2.7 版本需要 Java 7&#xff0c;2.6 以及更早期版本支持 Java 6Hadoop 3.x&#xff1a;最低要求…

配置BFD状态与接口状态联动示例

BFD简介 定义 双向转发检测BFD&#xff08;Bidirectional Forwarding Detection&#xff09;是一种全网统一的检测机制&#xff0c;用于快速检测、监控网络中链路或者IP路由的转发连通状况。 目的 为了减小设备故障对业务的影响&#xff0c;提高网络的可靠性&#xff0c;网…

深度学习实战65-人脸检测模型LFFD的搭建,LFFD模型的架构与原理的详细介绍

大家好,我是微学AI,今天给大家介绍一下深度学习实战65-人脸检测模型LFFD的搭建,LFFD模型的架构与原理的详细介绍。LFFD(Light and Fast Face Detector)模型是一种用于人脸检测的深度学习模型,其设计旨在实现轻量级和快速的人脸检测。本文将详细介绍LFFD模型的定义、优点、原…

【Linux】进程见通信之匿名管道pipe

1.匿名管道的特点 以下管道的统称仅代表匿名管道。 管道是一个只能单向通信的通信信道。为了实现进程间通信.管道是面向字节流的。仅限于父子通信或者具有血缘关系的进程进行进程见通信。管道自带同步机制&#xff0c;原子性写入。管道的生命周期是随进程的。 2.匿名管道通信…

SpringSecurity(五)

深入理解HttpSecurity的设计 一、HttpSecurity的应用 在前章节的介绍中我们讲解了基于配置文件的使用方式&#xff0c;也就是如下的使用。 也就是在配置文件中通过 security:http 等标签来定义了认证需要的相关信息&#xff0c;但是在SpringBoot项目中&#xff0c;我们慢慢脱离…

Java零基础——RocketMQ篇

1.RocketMQ简介 官网&#xff1a; http://rocketmq.apache.org/ RocketMQ是阿里巴巴2016年MQ中间件&#xff0c;使用Java语言开发&#xff0c;RocketMQ 是一款开源的分布式消息系统&#xff0c;基于高可用分布式集群技术&#xff0c;提供低延时的、高可靠的消息发布与订阅服…

03_阿里云_配置OSS环境变量

关于aliyunOSS文件上传的系统变量配置 问题引出 在黑马程序员2023新版JavaWeb开发教程教程中&#xff0c;P148Day11-04. 案例-文件上传-阿里云OSS-准备到P150Day11-06. 案例-文件上传-阿里云OSS-集成阿里云给的参考代码已经更新了&#xff0c;需要配置阿里云的用户变量&#…

K8S 删除命令空间时 一直卡住怎么办?

当使用完一个命名空间后&#xff0c;想删除了又删除不掉&#xff0c;这个时候查看命名空间的状态一直是Terminating。使用强制删除&#xff0c;也是还是不行。&#xff08;找了好多办法都不行&#xff09; [rootk8s-master kubernetes-yaml]# kubectl delete ns mem-example Er…

各种滤波算法的比较(GF、KF、EKF、UKF、PF)

目录 一、前言 二、滤波算法介绍 1、GF&#xff08;高斯滤波&#xff09; 2、KF&#xff08;卡尔曼滤波&#xff09; 3、EKF&#xff08;可扩展卡尔曼滤波&#xff09; 4、UKF&#xff08;无迹卡尔曼滤波&#xff09; 5、PF&#xff08;粒子滤波&#xff09; 三、不同滤…

elementui中添加开关控制

<template><!-- 图层管理 --><div class"home-wrapper"><div class"table-list"><div class"list"><el-table :data"tableData" height"100%" style"width: 100%;" border>&…