IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 【JavaScript】JS开发中五个常用功能/案例(41-45)(牛客题解) -> 正文阅读

[JavaScript知识库]【JavaScript】JS开发中五个常用功能/案例(41-45)(牛客题解)

🖥? NodeJS专栏:Node.js从入门到精通
🖥? 博主的前端之路:前端之行,任重道远(来自大三学长的万字自述)
🧧 个人社区:海底烧烤店ai(从前端到全栈)
🧑?💼个人简介:即将大三的学生,一个不甘平庸的平凡人🍬
👉 你的一键三连是我更新的最大动力??!
🏆分享博主自用牛客网🏆:一个非常全面的面试刷题求职网站,点击跳转🍬


前言

最近博主一直在牛客网刷题巩固基础知识,牛客网不仅具有公司真题专项练习面试题库在线编程等功能,还具有非常强大的AI模拟面试功能,简直是求职者的福音!

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

牛客网牛客网
在这里插入图片描述在这里插入图片描述

本篇文章所有示例来自于牛客网题库/在线编程/JS篇(41-45题),这些都是前端开发中常用的功能,借此记录一下刷题过程,巩固基础

一、查找dom共同节点

要求: 查找两个节点的最近的一个共同父节点,可以包括节点自身
输入描述:oNode1oNode2 在同一文档中,且不会为相同的节点

思路: 查找两个节点最近的一个共同节点,我们可以针对其中一个节点来进行操作(这里选择oNode1),先判断oNode1是否包含oNode2,否者的话就继续递归判断oNode1的父节点是否包含oNode2,直到包含条件成立就return出这个包含oNode2的节点

方案:

function commonParentNode(oNode1, oNode2) {
    if(oNode1.contains(oNode2)){
        return oNode1
    }else {
        return  commonParentNode(oNode1.parentNode,oNode2)
    }
}

API参考:

  • Node.parentNode:返回指定的节点在 DOM 树中的父节点。
  • Node.contains():判断传入的节点是否为该节点的后代节点。

二、修改函数 this 指向

要求: 实现 bindThis函数,它的作用是封装函数 f,使 fthis 指向指定的对象

思路: JS修改this指向有三种方法,分别是callapplybind,所以这个需求我们有三种实现方式,因为bindThis函数的目的是封装函数f,所以 bindThis函数的返回值应该是封装后的函数 f

知识点:callapplybind的区别?

callapply在改变this指向后会自动调用该函数,而bind在改变this指向后会返回改变this指向后的函数,并不会自动调用它

callapply都可以接收除了this指向以外的参数。
call后面的参数与原函数fn的参数是一一对应的。
apply的第二个参数是一个数组,数组中的元素是和原函数fn接收的参数一一对应的,这就是两者最大的区别。

方案1:使用call

因为bindThis方法需要返回封装后的f函数,我们暂且标记这个封装后的f函数为f1f.call(oTarget,...arguments)会将f函数的this指向改为oTarget,之后会将arguments参数数组中的所有参数作为函数的参数进行调用,并返回这个调用结果

这里这个arguments代表调用f1时传递的所有参数组成的数组

call里面使用...解构arguments是因为call后面的参数需要与原函数f的参数一一对应

arguments 是一个对应于传递给函数的参数的类数组对象

function bindThis(f, oTarget) {
    return function () { // 返回f1
        return f.call(oTarget,...arguments) // 将f1接收的参数传递给f进行调用
    }
}

方案2:使用apply

applycall大致相同,唯一的区别在于它接受的函数参数可以直接是一个数组,不需要我们手动解构arguments

function bindThis(f, oTarget) {
    return function () {
        return f.apply(oTarget,arguments) // 不需要...arguments
    }
}

方案3:使用bind

使用bind是最简单的,因为bind不会自动调用函数,只是将修改this指向后的函数返回,所以我们就不需要来回传递arguments参数数组了

function bindThis(f, oTarget) {
     return f.bind(oTarget)
}

三、根据包名,在指定空间中创建对象

要求: 根据包名,在指定空间中创建对象
输入描述:namespace({a: {test: 1, b: 2}}, 'a.b.c.d')
输出描述:{a: {test: 1, b: {c: {d: {}}}}}

思路:

  • 指定空间是以.间隔的字符串,我们可以直接使用split方法将其转为数组arrKey ,方便遍历
  • 声明一个变量obj,其初始值是浅拷贝的oNamespace(引用赋值),对obj的修改操作会直接影响到原对象oNamespace
  • 遍历arrKey ,遍历的当前属性在obj上不存在或者obj的该属性值不是一个对象时,设置obj的该属性值为一个空对象
  • 之后缩小obj为对应属性的值,随着遍历的进行,obj依次向后缩小,直到在指定空间中创建完成对象

方案:

function namespace(oNamespace, sPackage) {
    const arrKey = sPackage.split('.');
    let obj = oNamespace
    
    for(let key of arrKey) {
        // 如果属性不存在或者属性值不是一个对象
        if(!obj.hasOwnProperty(key) || Object.prototype.toString.call(obj[key])!=='[object Object]'){
            // 先设置属性值为对象
            obj[key]={}
        }
            // 缩小对象
            obj=obj[key]
    }
    // 因为对象赋值是引用赋值,所以上面对obj的修改操作会直接影响到原对象oNamespace,所以直接返回原对象即可
    return oNamespace
}

注意:

  • 这里判断数据类型时使用的是Object.prototype.toString.call(需要判断的数据)(对象原型链判断方法),之所以不使用typeof是因为它对于引用数据类型除了function返回'function',其余全部返回'object',并不能准确的判断一个数据是否为真正的对象

    Object.prototype.toString.call()适用于所有类型的判断检测,Object.prototype.toString.call(数据) 各种数据类型都能检测且检测精准,返回的是该数据类型的字符串

    Object.prototype.toString.call()原理:Object.prototype.toString 表示一个返回对象类型的字符串,call()方法可以改变this的指向,那么把Object.prototype.toString()方法指向不同的数据类型上面,就会返回不同的结果

  • hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键),这种方法只能检测对象的第一层属性,即{a:{b:9}}.hasOwnProperty('b') === false

四、数组去重

要求:Array 对象添加一个去除重复项的方法

示例:

输入:[false, true, undefined, null, NaN, 0, 1, {}, {}, 'a', 'a', NaN]
输出:[false, true, undefined, null, NaN, 0, 1, {}, {}, 'a']

思路: 利用Set对象将原数组转换成不含重复项Set结构,之后再转换回数组即可

方案:

Array.prototype.uniq = function () {
	// 这里的this指向的就是调用该方法的数组
    return Array.from(new Set(this))
}

五、 斐波那契数列

要求:JavaScript 实现斐波那契数列函数,返回第n个斐波那契数。 f(1) = 1, f(2) = 1f(n) = f(n-1) + f(n-2)

思路:斐波那契数列是最常见的一种算法了,最常见的解法是使用递归普通迭代(循环)

方案一:递归

n小于3时,即n为1和2时返回1,之后进行递归即可,这种方式性能较差

function fibonacci(n) {
     if(n<3) return 1
     return fibonacci(n-1) + fibonacci(n-2);
}

方案二:迭代(循环)

先提前定义好num1num2,分别代表f(1)f(2),之后循环依次向后迭代,num2变成f(3)num1变成f(2),依次类推,这种方法性能要比递归好,缺点就是不太易懂

function fibonacci(n) {
     var num1=1;
     var num2=1;
     for(var i=2;i<n;i++){
             num2+=num1;
             num1=num2-num1;
     }
     return num2;
}

结语

这篇文章的所有内容都出自于牛客网的JS篇题库
在这里插入图片描述

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

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

基础不牢,地动山摇! 快来和博主一起来牛客网刷题巩固基础知识吧!

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-15 01:54:56  更:2022-09-15 01:58:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:52:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码