Web前端最全你疏漏的 JS 函数硬核知识?这里帮你总结了(1),2024年最新腾讯三面后一直没消息

最后

中年危机是真实存在的,即便有技术傍身,还是难免对自己的生存能力产生质疑和焦虑,这些年职业发展,一直在寻求消除焦虑的依靠。

  • 技术要深入到什么程度?

  • 做久了技术总要转型管理?

  • 我能做什么,我想做什么?

  • 一技之长,就是深耕你的专业技能,你的专业技术。(重点)

  • 独立做事,当你的一技之长达到一定深度的时候,需要开始思考如何独立做事。(创业)

  • 拥有事业,选择一份使命,带领团队实现它。(创业)

一技之长分五个层次

  • 栈内技术 - 是指你的前端专业领域技术

  • 栈外技术 - 是指栈内技术的上下游,领域外的相关专业知识

  • 工程经验 - 是建设专业技术体系的“解决方案”

  • 带人做事 - 是对团队协作能力的要求

  • 业界发声 - 工作经验总结对外分享,与他人交流

永远不要放弃一技之长,它值得你长期信仰持有

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

主要内容包括html,css,html5,css3,JavaScript,正则表达式,函数,BOM,DOM,jQuery,AJAX,vue 等等。

在这里插入图片描述

解惑

上面的代码

var f = fn.bind(o, 1, 2)

的作用就是将 fn 函数拷贝了一份,名称叫做 f,同时将函数 f 中的 this 修改为对象o,所以函数 f 与 fn 的函数体是一样的,只不过内部 this 的指向不同了

如下代码,才是调用执行函数 f,而上面的代码仅仅完成上面的任务,但不会执行函数 fn 也不会执行新函数 f

f()

应用

页面中有1个div,默认为红色,鼠标悬浮后,变为蓝色,3秒之后恢复成红色

var div = document.querySelector(‘div’)

div.addEventListener(‘mouseover’, function () {

this.style.backgroundColor = ‘blue’

setTimeout(function () {

div.style.backgroundColor = ‘red’

}, 3000);

})

定时器中,this=window,所以不能使用this,必须使用元素名称div

当然可以使用 var that=this 的方式

但这两种方式都有问题,如实现下面的效果

当前页面上有3个div,默认都为红色,鼠标悬浮到某个div上,颜色变为蓝色,3秒后恢复成红色

var divs = document.querySelectorAll(‘div’)

for (var i = 0; i < divs.length; i++) {

divs[i].addEventListener(‘mouseover’, function () {

// 这里的this=当前触发事件的某个具体div

this.style.backgroundColor = ‘blue’

setTimeout(function () {

// 下面的代码应该怎么写

}, 3000);

})

}

定时器中的this=window,所以不能使用window

也不能使用divs[i],因为 i 的索引在事件发生时,并不是你想象中的索引

当然可以使用 that=this 的方式,但会多创建局部变量

可以利用bind方法

在这里插入图片描述

这里使用bind最合适,因为仅仅是修改了函数中this的指向,并不会马上执行,3秒之后由系统再次调用

注意:bind 方法会创建一个新函数,所以3秒后调用的是新函数,在新函数中,this=div

问?上面不是需要声明一个变量接收bind创建的新函数吗?为什么这里不需要?

同学,请先搞清楚:什么时候需要返回值,什么时候不需要

2.2.4 call、apply、bind三者的异同
  • 共同点 : 都可以改变this指向

  • 不同点:

  • call 和 apply 会调用函数, 并且改变函数内部this指向.

  • call 和 apply传递的参数不一样,call传递参数使用逗号隔开,apply使用数组传递

  • bind 不会调用函数, 可以改变函数内部this指向.

  • 应用场景

  1. call 经常做继承.

  2. apply经常跟数组有关系. 比如借助于数学对象实现数组最大值最小值

  3. bind 不调用函数,但是还想改变this指向. 比如改变定时器内部的this指向.

3.严格模式


3.1什么是严格模式

JavaScript 除了提供正常模式外,还提供了严格模式(strict mode)。ES5 的严格模式是采用具有限制性 JavaScript变体的一种方式,即在严格的条件下运行 JS 代码。

严格模式在 IE10 以上版本的浏览器中才会被支持,旧版本浏览器中会被忽略。

严格模式对正常的 JavaScript 语义做了一些更改:

1.消除了 Javascript 语法的一些不合理、不严谨之处,减少了一些怪异行为。

2.消除代码运行的一些不安全之处,保证代码运行的安全。

3.提高编译器效率,增加运行速度。

4.禁用了在 ECMAScript 的未来版本中可能会定义的一些语法,为未来新版本的 Javascript 做好铺垫。比如一些保留字如:class,enum,export, extends, import, super 不能做变量名

聊聊 TS

3.2开启严格模式

严格模式可以应用到整个脚本或个别函数中。因此在使用时,我们可以将严格模式分为为脚本开启严格模式和为函数开启严格模式两种情况。

  • 脚本开启严格模式

  • 函数开启严格模式

3.3严格模式中的变化

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode

严格模式对 Javascript 的语法和行为,都做了一些改变。

‘use strict’

num = 10

console.log(num)//严格模式后使用未声明的变量


var num2 = 1;

delete num2;//严格模式不允许删除变量:删除变量的目的是希望释放内存,处理方式一般是将变量的值设置为null


function fn() {

console.log(this); // 严格模式下全局作用域中函数中的 this 是 undefined

}

fn();

--------------------------------------------------------------------------------- function Star() {

this.gender = ‘男’;

}

// 不加new 调用Star,则this=undefined

console.log(Star().gender)

// 加new 调用Star,则this=对象

console.log(new Star().gender)


setTimeout(function() {

console.log(this); //严格模式下,定时器 this 还是指向 window

}, 2000);

另外,严格模式下函数的参数名称应该唯一

// 非严格模式下

function f1(m, m) {

console.log(m + m)

}

f1(1,2) // 4,分析一下原因为什么事4

严格模式下,会报错

4.高阶函数


高阶函数是对其他函数进行操作的函数,它接收函数作为参数或将函数作为返回值输出。

函数作为参数:

在这里插入图片描述

函数作为返回值

在这里插入图片描述

函数也是一种数据类型,同样可以作为参数,传递给另外一个参数使用。最典型的就是作为回调函数。

同理函数也可以作为返回值传递回来

函数作为参数案例:

function fn(m, n, callback) {

console.log(m + n)

// 函数主体执行结束后才会执行回调函数

callback && callback()

}

fn(3, 4, function () {

console.log(‘我就是回调函数’)

})

jquery 中大量应用了回调函数,比如动画完成后执行某个操作

5.闭包


5.1变量的作用域复习

变量根据作用域的不同分为两种:全局变量和局部变量。

  1. 函数内部可以使用全局变量。

  2. 函数外部不可以使用局部变量。

  3. 当函数执行完毕,本作用域内的局部变量会销毁。

5.2什么是闭包

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures

在JS中,函数每次创建,都会生成闭包(closure),这个闭包包含函数及其词法环境(大概类似于执行上下文)

闭包是一种执行机制:内部函数总是可以访问其所在的外部函数中声明的变量和参数,即使在其外部函数执行结束之后

/*

在一个函数中又嵌套函数,在JS中是没有问题的

1)内部作用域可以访问外部作用域,所以f2中可以访问f1中的变量

2)在全局作用域内,不访问函数f1中的变量

*/

function f1() {

var m = 100

return function() {

console.log(m)

}

}

var myfunc=f1()

// myfunc 是一个变量,引用了f2的地址,myfunc() 就相当于执行了 f2()

myfunc() // f2()

// console.log(m)

通过上面案例发现:闭包可以延伸变量的作用范围。

解惑

一般情况下,下面代码执行后,外部函数f1就执行完毕了,那么函数内部的成员数据都会被销毁,包括变量 m,但是因为内部函数f2使用了变量m,而函数f2又被返回给了变量 myfunc,即变量myfuc引用了内部函数f2,此时

f2还没有执行,所以外部函数f1就不能释放自己的变量m

f1()

我们可以将 子函数f2 称作闭包函数(有争议)

我们再对闭包做一个总结:函数创建时,形成一个闭包,闭包让内部函数可以访问外部函数的变量和参数,并且通过向外返回内部函数,使得在函数外部也可以访问函数内部的数据

闭包的三个特性

1)函数嵌套函数

2)函数内部可以访问函数外部的变量和参数

3)外部函数执行完毕后,参数和变量不会被垃圾回收机制回收

5.3闭包的案例

  1. 利用闭包的方式得到当前li 的索引号

for (var i = 0; i < lis.length; i++) {

// 利用for循环创建了4个立即执行函数

// 立即执行函数也成为小闭包因为立即执行函数里面的任何一个函数都可以使用它的i这变量

(function(i) {

lis[i].onclick = function() {

console.log(i);

}

})(i);

}

但是,这种案例使用闭包其实并不是最好的解决方案,因为每次循环都要创建一个函数,而且每个i 的值都会被保存,不能释放,所以执行效率会低

将i的值存储于li标签的自定义属性中的方式更加可取

代码 (任务单)

  1. 闭包应用-3秒钟之后,打印所有li元素的内容

下面代码遍历所有li标签,创建了三个定时器,3秒之后打印每个li标签元素内容

for (var i = 0; i < lis.length; i++) {

(function(i) {

setTimeout(function() {

console.log(lis[i].innerHTML);

}, 3000)

})(i);

}

其实,使用我们前面学习的 bind 方法也是可以的

代码 (任务单)

  1. 闭包应用-计算打车价格

/*需求分析

打车起步价13(3公里内), 之后每多一公里增加 5块钱. 用户输入公里数就可以计算打车价格

如果有拥堵情况,总价格多收取2块钱拥堵费*/

var car = (function () {

var start_price = 13

var start_juli = 3

var total = 0

return {

price: function (juli) {

if (juli <= start_juli) {

total = start_price

} else if (juli > 3) {

total = start_price + (juli - start_juli) * 5

}

return total

},

yondu: function (flag) {

return flag ? total + 2 : total

}

}

})()

console.log(car.price(3));

console.log(car.price(10));

console.log(car.yondu(false));

console.log(car.yondu(true));

解惑

1、立即执行函数中的代码立即执行,不会等待调用,所以 变量 car 引用的是一个对象

2、引用的对象中包含两个函数 price 和 yongdu,这两个函数属于立即执行函数的子函数

3、子函数中引用了外部函数中的变量,所以形成了闭包

4、上面的案例并非非要这么编写程序,只是为了练习闭包的使用

6.递归


6.1什么是递归

**递归:**如果一个函数在内部可以调用其本身,那么这个函数就是递归函数。简单理解:函数内部自己调用自己, 这个函数就是递归函数

**注意:**递归函数的作用和循环效果一样,由于递归很容易发生“栈溢出”错误(stack overflow),所以必须要加退出条件return。

在这里插入图片描述

6.2利用递归求1~n的阶乘

//利用递归函数求1~n的阶乘 1 * 2 * 3 * 4 * …n

function fn(n) {

if (n == 1) { //结束条件

return 1;

}

return n * fn(n - 1);

}

console.log(fn(3));

在这里插入图片描述

6.3利用递归求斐波那契数列

// 利用递归函数求斐波那契数列(兔子序列) 1、1、2、3、5、8、13、21…

// 用户输入一个数字 n 就可以求出 这个数字对应的兔子序列值

自学几个月前端,为什么感觉什么都没学到??


这种现象在很多的初学者和自学前端的同学中是比较的常见的。

因为自学走的弯路是比较的多的,会踩很多的坑,学习的过程中是比较的迷茫的。

最重要的是,在学习的过程中,不知道每个部分该学哪些知识点,学到什么程度才算好,学了能做什么。

很多自学的朋友往往都是自己去找资料学习的,资料上有的或许就学到了,资料上没有的或许就没有学到。

这就会给人一个错误的信息就是,我把资料上的学完了,估计也-就差不多的了。

但是真的是这样的吗?非也,因为很多人找的资料就是很基础的。学完了也就是掌握一点基础的东西。分享给你一份前端分析路线,你可以参考。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

还有很多的同学在学习的过程中一味的追求学的速度,很快速的刷视频,写了后面忘了前面,最后什么都没有学到,什么都知道,但是什么都不懂,要具体说,也说不出个所以然。

所以学习编程一定要注重实践操作,练习敲代码的时间一定要多余看视频的时间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值