JavaScriptJS开发中五个常用功能/案例(41-45)(牛客题解)
Posted 海底烧烤店ai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScriptJS开发中五个常用功能/案例(41-45)(牛客题解)相关的知识,希望对你有一定的参考价值。
🖥️ NodeJS专栏:Node.js从入门到精通
🖥️ 博主的前端之路:前端之行,任重道远(来自大三学长的万字自述)
🧧 个人社区:海底烧烤店ai(从前端到全栈)
🧑💼个人简介:即将大三的学生,一个不甘平庸的平凡人🍬
👉 你的一键三连是我更新的最大动力❤️!
🏆分享博主自用牛客网🏆:一个非常全面的面试刷题求职网站,点击跳转🍬
文章目录
前言
最近博主一直在牛客网刷题巩固基础知识,牛客网不仅具有公司真题、专项练习、面试题库、在线编程等功能,还具有非常强大的AI模拟面试功能,简直是求职者的福音!
牛客网里的题库非常全面的,无论你是前端还是后端,是想要备考还是准备面试又或者是想要提高自己,你都能在牛客网上找到适合自己的题,赶快点击链接去注册登录吧:点我进入牛客网
牛客网 | 牛客网 |
---|---|
本篇文章所有示例来自于牛客网题库/在线编程/JS篇
(41-45题),这些都是前端开发中常用的功能,借此记录一下刷题过程,巩固基础
一、查找dom共同节点
要求: 查找两个节点的最近的一个共同父节点,可以包括节点自身
输入描述:oNode1
和 oNode2
在同一文档中,且不会为相同的节点
思路: 查找两个节点最近的一个共同节点,我们可以针对其中一个节点来进行操作(这里选择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
,使 f
的 this
指向指定的对象
思路: JS
修改this
指向有三种方法,分别是call
、apply
、bind
,所以这个需求我们有三种实现方式,因为bindThis
函数的目的是封装函数f
,所以 bindThis
函数的返回值应该是封装后的函数 f
知识点:call
、apply
、bind
的区别?
call
与apply
在改变this
指向后会自动调用该函数,而bind
在改变this
指向后会返回改变this
指向后的函数,并不会自动调用它
call
和apply
都可以接收除了this
指向以外的参数。
call
后面的参数与原函数fn
的参数是一一对应的。
apply
的第二个参数是一个数组,数组中的元素是和原函数fn
接收的参数一一对应的,这就是两者最大的区别。
方案1:使用call
因为bindThis
方法需要返回封装后的f
函数,我们暂且标记这个封装后的f
函数为f1
,f.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
apply
与call
大致相同,唯一的区别在于它接受的函数参数可以直接是一个数组,不需要我们手动解构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) = 1
,f(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);
方案二:迭代(循环)
先提前定义好num1
和num2
,分别代表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
题库非常贴合实际的,在写的过程中自己查漏补缺,收获了很多,强烈将牛客网推荐给大家!
如果本篇文章对你有所帮助,还请客官一件四连!❤️
以上是关于JavaScriptJS开发中五个常用功能/案例(41-45)(牛客题解)的主要内容,如果未能解决你的问题,请参考以下文章
JavaScriptJS开发中五个常用功能/案例(31-35)(牛客题解)
我正在编写一个代码,该代码从用户那里获取公司中五个项目的数量输入
JavaScript五个常用功能/案例:计时器 | 流程控制 | 闭包应用 | arguments剩余参数 | 二次封装函数