定制开发小程序【JavaScript】手撕前端面试题:手写new操作符 | 手写Object.freeze

🖥️ NodeJS专栏:
🖥️ 定制开发小程序博主的前端之路(定制开发小程序源创征文一等奖作品):
🖥️ TypeScript知识总结:
🧑‍💼个人简介:大三学生,定制开发小程序一个不甘平庸的平凡人🍬
👉 定制开发小程序你的一键三连是我更新定制开发小程序的最大动力❤️!
🏆定制开发小程序分享博主自用牛客网🏆:


文章目录

前言

定制开发小程序向大家推荐一款博主一定制开发小程序直在用的面试刷题求职网站:

牛客网不仅具有公司真题专项练习面试题库在线编程等功能,定制开发小程序还具有非常强大的AI模拟面试功能,定制开发小程序简直是求职者的福音!

定制开发小程序牛客网里的题库非常全面的,定制开发小程序无论你是前端还是后端,是想要备考还是准备面试又或者是想要提高自己,你都能在牛客网上找到适合自己的题,赶快点击链接去注册登录吧:

牛客网牛客网

本篇文章所有示例参考自题库/在线编程/JS篇

1、手写new操作符

要求

补全JavaScript代码,要求实现new操作符的功能。


介绍如下:

new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。

参数:

  • constructor
    一个指定对象实例的类型的类或函数。

  • arguments
    一个用于被 constructor 调用的参数列表。

new 关键字会进行如下的操作:

  1. 创建一个空的简单 JavaScript 对象(即 {});
  2. 为步骤 1 新创建的对象添加属性 __proto__,将该属性链接至构造函数的原型对象(设置它的原型为构造函数的原型对象);
  3. 将步骤 1 新创建的对象作为 this 的上下文;
  4. 如果该函数没有返回对象,则返回 this

手撕代码

const _new = function () {    // 补全代码    // 1. 创建一个空的简单 `JavaScript` 对象(即 `{}`);    // 2. 为步骤 1 新创建的对象添加属性 `__proto__`,将该属性链接至构造函数的原型对象(设置它的原型为构造函数的原型对象);    // 3. 将步骤 1 新创建的对象作为 `this` 的上下文;    // 4. 如果该函数没有返回对象,则返回 `this`。    const obj1 = {}; // 1    const Fn = arguments[0]; // 获取函数参数    Object.setPrototypeOf(obj1, Fn.prototype); // 2     const obj2 = Fn.apply(obj1, [].slice.call(arguments, 1)) // 3     return obj2 instanceof Object ? obj2 : obj1; // 4}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

[].slice.call(arguments, 1)的作用是获得一个arguments的拷贝数组,且该数组不含arguments的第一个元素。

我们知道数组的slice方法能够截取原数组的部分内容(返回一个新数组,不会修改原数组),但参数数组arguments是一个并不具有slice这个方法,所以这里使用call[].slicethis指定到arguments

测试一下:

function Fn(age) {    this.name = 'Ailjx'    this.age = age}console.log('new', new Fn(18));console.log('_new', _new(Fn, 18));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2、手写Object.freeze

要求

补全JavaScript代码,要求实现Object.freeze函数的功能且该新函数命名为"_objectFreeze"


函数介绍如下:

Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改freeze() 返回和传入的参数相同的对象。

参数:

  • obj
    要被冻结的对象。

返回值:

  • 被冻结的对象。

手撕代码

需要注意的是:

  1. 注意不可枚举的属性也要重新冻结。
  2. 注意 Symbol 类型作为 key 值的情况,也要冻结。
  3. 注意只冻结对象自有的属性(使用 for ... in 会把原型链上的可枚举属性遍历出来)。
  4. 注意不可扩展性(不能添加新属性,使用 Object.preventExtensions()搭配configurable: falseObject.seal() 实现,同时也相当于把原型链冻结)。
const _objectFreeze = object => {    // 补全代码    if (typeof object !== 'object' || object === null) {        throw new TypeError(`the ${object} is not a object`)    }    // Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括 Symbol 值作为名称的属性)组成的数组。    const keys = Object.getOwnPropertyNames(object);    // Object.getOwnPropertySymbols() 方法返回一个给定对象自身的所有 Symbol 属性的数组。    const symbols = Object.getOwnPropertySymbols(object);        [...keys, ...symbols].forEach(key => {        // Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。        Object.defineProperty(object, key, {            // 当且仅当该属性的 configurable 键值为 true 时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。            // configurable: false, // 如果下面使用的是Object.preventExtensions(object)而不是Object.seal(),则需要设置configurable: false            			// 当 writable 属性设置为 false 时,该属性被称为“不可写的”。它不能被重新赋值            writable: false,        })    })    // Object.seal()方法封闭一个对象,    // 阻止添加新属性并将所有现有属性标记为不可配置。    // 当前属性的值只要原来是可写的就可以改变。    // 不会影响从原型链上继承的属性。但 __proto__ ( 已弃用 ) 属性的值也会不能修改。    // Object.seal的效果相当于: 在Object.defineProperty时将configurable设置成false,同时对对象调用Object.preventExtensions。    Object.seal(object)    // Object.preventExtensions()方法让一个对象变的不可扩展,也就是永远不能再添加新的属性。    // 该方法使得目标对象的 [[prototype]] 不可变;任何重新赋值 [[prototype]] 操作都会抛出 TypeError 。这种行为只针对内部的 [[prototype]] 属性,目标对象的其它属性将保持可变。    // Object.preventExtensions(object)         return object}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

知识点:

  • 方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性不包括 Symbol 值作为名称的属性)组成的数组。
  • 方法返回一个给定对象自身的所有 Symbol 属性的数组。
  • 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
  • 方法封闭一个对象,阻止添加新属性并将所有现有属性标记为不可配置。当前属性的值只要原来是可写的就可以改变。效果相当于: 在Object.defineProperty时将configurable设置成false,同时对对象调用Object.preventExtensions
  • 方法让一个对象变的不可扩展,也就是永远不能再添加新的属性。
    • Object.preventExtensions只防止添加属性,即不可扩展。
    • Object.seal除了不可扩展,也不可配置。
    • Object.freeze就像freeze的意思是被冻结,除了不可扩展,不可配置,也不可重写。

结语

这篇文章的所有内容都出自于:

牛客网的JS题库非常贴合实际的,在写的过程查漏补缺能收获了很多,强烈将推荐给大家!

如果本篇文章对你有所帮助,还请客官一件四连!❤️

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发