JS面试必备之手写call/apply/bind/new

以下是关于“JS面试必备之手写call/apply/bind/new”的完整攻略。

手写call和apply

call和apply是JavaScript原生的方法,可以改变函数的this指向。下面是手写实现call和apply的步骤:

call

  1. 将函数作为对象的一个属性。
  2. 将函数的this指向当前对象。
  3. 执行该函数。
  4. 将对象上的函数删除。
Function.prototype.myCall = function (context = window, ...args) {
  let fn = Symbol();
  context[fn] = this;
  let result = context[fn](...args);
  delete context[fn];
  return result;
}

apply

  1. 将函数作为对象的一个属性。
  2. 将函数的this指向当前对象。
  3. 执行该函数。
  4. 将对象上的函数删除。
Function.prototype.myApply = function (context = window, args) {
  let fn = Symbol();
  context[fn] = this;
  let result = context[fn](...args);
  delete context[fn];
  return result;
}

代码中的context是传入的上下文对象,如果不传入则默认为window。

示例:

let obj = {
  name: '小明'
}

function sayHi(age, gender) {
  console.log(`我叫${this.name},我今年${age}岁了,我是${gender}。`);
}

sayHi.myCall(obj, 18, '男'); // 我叫小明,我今年18岁了,我是男。
sayHi.myApply(obj, [18, '男']); // 我叫小明,我今年18岁了,我是男。

手写bind

bind方法可以创建一个新的函数,将原函数的this指向指定对象,并返回该新函数。下面是手写实现bind方法的步骤:

  1. 返回一个新函数。
  2. 将新函数的this指向传入的对象。
  3. 将新函数的参数传递给原函数。
  4. 如果新函数被实例化,需要将原函数的原型链赋值给新函数,以保证原函数的属性和方法可以被继承。
Function.prototype.myBind = function (context = window, ...args) {
  let self = this;
  return function (...newArgs) {
    if (this instanceof self) {
      self.apply(this, [...args, ...newArgs]);
    } else {
      context[self.name] = self;
      context[self.name](...args, ...newArgs);
      delete context[self.name];
    }
  }
}

示例:

let obj1 = {
  name: '小明',
  sayHi(age) {
    console.log(`我叫${this.name},我今年${age}岁了。`);
  }
}
let obj2 = {
  name: '小红'
}

let sayHi = obj1.sayHi.myBind(obj2, 18);

sayHi(); // 我叫小红,我今年18岁了。
let person = new sayHi(); // person.sayHi is not a function

手写new

new操作符主要实现以下几步操作:

  1. 创建一个新对象。
  2. 将该新对象的原型链指向构造函数的prototype。
  3. 将构造函数的this指向该新对象。
  4. 执行构造函数,获得返回值。
  5. 如果构造函数返回值为基本类型,则返回新创建的对象,否则返回构造函数的返回值。
function myNew() {
  let obj = new Object();
  let Constructor = [].shift.call(arguments);
  obj.__proto__ = Constructor.prototype;
  let result = Constructor.apply(obj, arguments);
  return typeof result === 'object' ? result || obj : obj;
}

示例:

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.sayHi = function () {
  console.log(`我叫${this.name},我今年${this.age}岁了。`);
}

let person1 = myNew(Person, '小明', 18);
let person2 = new Person('小红', 19);

person1.sayHi(); // 我叫小明,我今年18岁了。
person2.sayHi(); // 我叫小红,我今年19岁了。

总结:通过手写call、apply、bind和new的实现,不仅可以帮助我们更好地理解和掌握这些方法的使用,同时也可以在面试中展示我们的js基础知识和编程技能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JS面试必备之手写call/apply/bind/new - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • Egg Vue SSR 服务端渲染数据请求与asyncData

    Egg Vue SSR 是一个基于 Egg.js 和 Vue.js 的服务端渲染项 目,它能够将 Vue.js 组件在服务端渲染完成之后再返回给客户端,在一定程度上可以提高页面的首屏渲染速度和搜索引擎的爬取效果。为了更好的支持服务端渲染,Egg Vue SSR 提供了异步数据请求方法 asyncData。 asyncData 是在服务端执行的方法,而非在浏览…

    JavaScript 2023年6月11日
    00
  • js表单元素checked、radio被选中的几种方法(详解)

    当我们需要在Web页面中收集用户输入时,表单是不可缺少的工具之一。而表单元素中的checkbox和radio这两种类型的输入框对于选项的选择有着重要的作用。然而,如何通过JavaScript获取选中的checkbox或radio的值呢?下面我们将详细讲解这个问题。 1. checked属性 对于单个的checkbox,我们可以通过其checked属性来检查其…

    JavaScript 2023年6月10日
    00
  • 将json对象转换为字符串的方法

    将JSON对象转换为字符串通常使用JSON.stringify()方法,以下是该方法的完整攻略: 1. JSON.stringify()方法的语法 JSON.stringify()方法的语法如下: JSON.stringify(value[, replacer[, space]]) 其中,value参数表示待转换的JSON对象,必选且只能是以下类型之一:- …

    JavaScript 2023年5月27日
    00
  • JS字符串补全方法padStart()和padEnd()

    一、JS字符串补全方法概述 在 ES2017 中,新增了两个字符串方法:padStart 和 padEnd。这两个方法主要用于在字符串开头或结尾填充指定的字符串使其达到给定的长度。这些方法可以很方便地增强字符串格式化的能力。 padStart():在当前字符串开头填充指定的字符串,直到达到指定的长度。如果当前字符串的长度大于或等于指定的长度,则返回原始字符串…

    JavaScript 2023年5月28日
    00
  • JavaScript高级程序设计(第3版)学习笔记11 内建js对象

    下面是《JavaScript高级程序设计(第3版)学习笔记11 内建js对象》的学习攻略。 常用内建对象 JavaScript中内建对象众多,本章介绍的是一些常用的内建对象。 Boolean对象 Boolean对象只有两种可能的实例,即true和false,如果将其他数据类型转换为Boolean类型,规则是:除了””、0、NaN、null和undefined…

    JavaScript 2023年5月18日
    00
  • MutationObserver监视对DOM 树所做更改的功能妙用

    MutationObserver是一种Web API,它可以监视对DOM树所做的更改,并在更改发生时触发回调函数。它可以监视DOM的三类更改:子节点树的更改、属性的更改以及文本内容的更改。MutationObserver的用途非常广泛,特别是在与React、Vue等前端框架结合使用时,可以帮助我们轻松地实现数据绑定、自定义指令等功能。 MutationObs…

    JavaScript 2023年6月11日
    00
  • 详解Eslint 配置及规则说明

    我来详细讲解一下“详解Eslint 配置及规则说明”。 什么是Eslint? Eslint是一款JavaScript代码检查工具,用于检查代码是否符合规范。它可以帮助我们发现代码中的错误和潜在的问题,并且可以帮助我们规范代码风格,从而提高代码的可读性和可维护性。 配置Eslint 要使用Eslint,我们首先需要在项目中安装Eslint并进行基础配置。下面是…

    JavaScript 2023年6月11日
    00
  • JavaScript数组方法-系统性总结详解

    JavaScript数组方法-系统性总结详解 概述 数组(Array)是JavaScript中最常用、最重要的一种数据类型,而且在实际开发中,我们也经常需要对数组进行各种操作,比如查询、增加、删除、排序等等。JavaScript提供了很多数组方法,让我们能够方便快捷的对数组进行各种操作,使得开发变得更加高效。本篇文章旨在对JavaScript数组方法进行系统…

    JavaScript 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部