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

news2024/11/30 1:36:39

分享一个基础面试题---手写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??window
	var 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和null
	if (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.coloradmin.cn/o/1290778.html

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

相关文章

Vue2与Vue3的语法对比

Vue2与Vue3的语法对比 Vue.js是一款流行的JavaScript框架&#xff0c;通过它可以更加轻松地构建Web用户界面。随着Vue.js的不断发展&#xff0c;Vue2的语法已经在很多应用中得到了广泛应用。而Vue3于2020年正式发布&#xff0c;带来了许多新的特性和改进&#xff0c;同时也带来…

unity 2d 入门 飞翔小鸟 飞翔脚本(五)

新建c#脚本 using System.Collections; using System.Collections.Generic; using UnityEngine;public class Fly : MonoBehaviour {//获取小鸟&#xff08;刚体&#xff09;private Rigidbody2D bird;//速度public float speed;// Start is called before the first frame up…

浅谈web性能测试

什么是性能测试&#xff1f; web性能应该注意些什么&#xff1f; 性能测试&#xff0c;简而言之就是模仿用户对一个系统进行大批量的操作&#xff0c;得出系统各项性能指标和性能瓶颈&#xff0c;并从中发现存在的问题&#xff0c;通过多方协助调优的过程。而web端的性能测试…

【华为数据之道学习笔记】2-建立企业级数据综合治理体系

数据作为一种新的生产要素&#xff0c;在企业构筑竞争优势的过程中起着重要作用&#xff0c;企业应将数据作为一种战略资产进行管理。数据从业务中产生&#xff0c;在IT系统中承载&#xff0c;要对数据进行有效治理&#xff0c;需要业务充分参与&#xff0c;IT系统确保遵从&…

若依项目前后端部署记录

前言 本文较乱&#xff0c;用于笔者记录项目部署过程&#xff0c;对于想学习若依项目部署的同学看文章可能会导致误导&#xff0c;建议读者多查资料&#xff0c;保持疑问并谨慎验证。 项目官方指导&#xff1a; 环境部署 | RuoYi 1、环境部署相关 JDK > 1.8 (推荐1.8版本…

TIMO后台管理系统 Shiro 反序列化漏洞复现

0x01 产品简介 TIMO 后台管理系统,基于SpringBoot2.0 + Spring Data Jpa + Thymeleaf + Shiro 开发的后台管理系统,采用分模块的方式便于开发和维护,支持前后台模块分别部署,目前支持的功能有:权限管理、部门管理、字典管理、日志记录、文件上传、代码生成等,为快速开发后…

记录 | vscode pyhton c++调试launch.json配置

下面提供 vscode 中 python 和 c 调试配置的 launch.json (好用&#xff0c;已用好几年&#xff0c;建议收藏) {// 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。// 欲了解更多信息&#xff0c;请访问: https://go.microsoft.com/fwlink/?linkid830387&qu…

多人聊天UDP

服务端 package 多人聊天;import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList;…

神经网络 模型表示(一)

神经网络 模型表示 模型表示一 为了构建神经网络模型&#xff0c;我们需要首先思考大脑中的神经网络是怎样的&#xff1f;每一个神经元都可以被认为是一个处理单元/神经核&#xff08;processing unit/Nucleus&#xff09;&#xff0c;它含有许多输入/树突&#xff08;input/…

分布式分布式事务分布式锁分布式ID

目录 分布式分布式系统设计理念目标设计思路中心化去中心化 基本概念分布式与集群NginxRPC消息中间件&#xff08;MQ&#xff09;NoSQL&#xff08;非关系型数据库&#xff09; 分布式事务1 事务2 本地事务3 分布式事务4 本地事务VS分布式事务5 分布式事务场景6 CAP原理7 CAP组…

PACS源码,医学影像传输系统源码,全院级应用,支持放射、超声、内窥镜、病理等影像科室,且具备多种图像处理及三维重建功能

​三维智能PACS系统源码&#xff0c;医学影像采集传输系统源码 PACS系统以大型关系型数据库作为数据和图像的存储管理工具&#xff0c;以医疗影像的采集、传输、存储和诊断为核心&#xff0c;集影像采集传输与存储管理、影像诊断查询与报告管理、综合信息管理等综合应用于一体的…

Arrarys类的相关细节与知识点

Arrarys类在Java中存储了一些对数组操作的一些方法&#xff0c;比如Sort()&#xff0c;toString&#xff0c;BinarySearch()&#xff0c;copyof()&#xff0c;fill()&#xff0c;equals()&#xff0c;aList这几种方法&#xff0c;这里面最重要的可能就是Sort()方法&#xff0c;…

AWS 日志分析工具

当您的网络资源托管在 AWS 中时&#xff0c;需要定期监控您的 AWS CloudTrail 日志、Amazon S3 服务器日志和 AWS ELB 日志等云日志&#xff0c;以降低任何潜在的安全风险、识别严重错误并确保满足所有合规性法规。 什么是 Amazon S3 Amazon Simple Storage Service&#xff…

汽车网络安全--ISO\SAE 21434解析(二)

1.风险评估方法 书接上文,我们正式开始对车灯系统的TARA分析,首先回顾下整车关于车灯系统描述: 可以比较肯定的是,我们定义的item为车灯系统,因此可以看到上图中画出了item boundary;同时定义出运行环境,个人理解,这块就是为TARA分析提供足够的环境支撑,不管是直接还…

RabbitMQ创建新用户,并给用户添加角色和授权

一、进入容器 1.1 查看运行容器的详细信息 docker ps -a1.2 进入容器命令 docker exec -it 容器ID /bin/bash 或 docker exec -it 容器name bash 1.3 退出容器命令 exit 或者 CtrlQP 二、操作RabbitMQ 2.1 查看用户列表 注:先进入到容器内部 rabbitmqctl list_user…

区块链媒体:Web3.015个方法解析-华媒舍

Web3.0是第三代互联网的发展阶段&#xff0c;相较于Web2.0&#xff0c;它具有更高的可信性、安全性和去中心化特点。在Web3.0时代&#xff0c;推广变得更为重要&#xff0c;因为吸引用户和提高品牌知名度对于在竞争激烈的市场中脱颖而出至关重要。本文将揭秘推广Web3.0的15个秘…

短视频购物系统源码:构建创新购物体验的技术深度解析

短视频购物系统作为电商领域的新宠&#xff0c;其背后的源码实现是其成功的关键。本文将深入探讨短视频购物系统的核心技术和源码设计&#xff0c;以揭示其如何构建创新购物体验的技术奥秘。 1. 技术架构与框架选择 短视频购物系统的源码首先考虑的是其技术架构。常见的选择…

Hazelcast分布式内存网格(IMDG)基本使用,使用Hazelcast做分布式内存缓存

文章目录 一、Hazelcast简介1、Hazelcast概述2、Hazelcast之IMDG3、数据分区 二、Hazelcast配置1、maven坐标2、集群搭建&#xff08;1&#xff09;组播自动搭建 3、客户端4、集群分组5、其他配置 三、Hazelcast分布式数据结构1、IMap2、IQueue&#xff1a;队列3、MultiMap4、I…

JavaWeb(十)

一、JavaWeb概述 Web&#xff1a;全球广域网&#xff0c;也称为万维网(www)&#xff0c;能够通过浏览器访问的网站。 JavaWeb&#xff1a;使用 Java技术进行web互联网开发。 二、JavaWeb 技术栈 2.1、B/S 架构 B/S 架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器…