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

yizhihongxing

以下是关于“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日

相关文章

  • JS在浏览器中解析Base64编码图像

    在浏览器中解析Base64编码图像可以使用JavaScript来实现,下面是实现的步骤和相应的示例代码。 1. 将Base64编码字符串转换为Blob对象 使用atob()函数将Base64编码字符串转换为二进制数据,然后将其转换为Blob对象。 // 示例1:将Base64编码字符串转换为Blob对象 const base64 = ‘data:image/…

    JavaScript 2023年5月19日
    00
  • JavaScript快速入门(二)

    文件中引入JavaScript 嵌入到HTML文件中 在body或者head中添加script标签 <script> var age = 10; console.log(age); </script> 引入js文件 创建一个js文件 var age = 20; console.log(age); 在html文件中src引入改文件 &l…

    JavaScript 2023年4月18日
    00
  • vue3的api解读之ref和reactive示例详解

    下面是针对“vue3的api解读之ref和reactive示例详解”的完整攻略: 1. 什么是 ref 和 reactive? ref: 用来创建一个响应式对象,它会返回一个带有 value 属性的对象,这个 value 属性可以自动更新页面。 reactive:用来创建一个响应式对象,它会将对象中所有属性都转化为响应式数据,任何一个属性发生变化都能触发相应…

    JavaScript 2023年6月11日
    00
  • 详解JavaScript中的链式调用

    下面我来详细讲解一下JavaScript中的链式调用。 什么是链式调用 链式调用指的是在一个对象上连续调用多个方法,实现简洁明了的代码结构。例如: obj.method1().method2().method3(); 其中,obj是一个对象,method1()、method2()、method3()是该对象上的三个方法。链式调用可以让代码更加简洁和易读,同时…

    JavaScript 2023年5月19日
    00
  • JavaScript包装对象使用详解

    JavaScript包装对象使用详解 在JavaScript中,有三种基本数据类型:字符串、数字和布尔值。但是在实际开发中,我们通常需要使用更复杂的数据类型,这时就需要使用JavaScript的包装对象。 什么是JavaScript包装对象 JavaScript提供了三种基本类型的包装对象:String、Number和Boolean。当我们在基本类型上调用一…

    JavaScript 2023年5月27日
    00
  • JavaScript MutationObserver实例讲解

    下面是关于“JavaScript MutationObserver实例讲解”的详细攻略。 什么是MutationObserver MutationObserver是在现代浏览器中新增的监视DOM元素变化的API。它提供了一种能够在DOM对象发生变化时,异步被通知的能力。 如何使用MutationObserver MutationObserver是一个构造函数…

    JavaScript 2023年6月10日
    00
  • JS数组转字符串实现方法解析

    下面是“JS数组转字符串实现方法解析”的完整攻略。 前言 在实际的开发中,我们经常需要将 JavaScript 数组转换为字符串。这个过程并不复杂,但是我们需要注意一些细节,否则可能会出现不符合预期的结果。 本文将介绍多种将 JavaScript 数组转换为字符串的方法,其中涉及到 join() 方法、toString() 方法、JSON.stringify…

    JavaScript 2023年5月28日
    00
  • js判断浏览器的比较全的代码

    判断浏览器的代码可以在不同的场景下使用,例如可以根据不同浏览器进行兼容性处理,或者在不同浏览器下加载不同的样式和功能等。以下是一个比较全面的判断浏览器的代码: var userAgent = navigator.userAgent; //获取浏览器的userAgent字符串 var isOpera = userAgent.indexOf("Oper…

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