你疏漏的 JS 函数硬核知识?这里帮你总结了

}())

2.this


2.1函数内部的this指向

这些 this 的指向,是当我们调用函数的时候确定的。调用方式的不同决定了this 的指向不同

一般指向我们的调用者.

在这里插入图片描述

2.2改变函数内部 this 指向

2.2.1 call方法

call()方法调用一个对象。简单理解为调用函数的方式,但是它可以改变函数的 this 指向

应用场景: 经常做继承.

var o = {

name: ‘andy’

}

function fn(a, b) {

console.log(this);

console.log(a+b)

};

fn(1,2)// 此时的this指向的是window 运行结果为3

fn.call(o,1,2)//此时的this指向的是对象o,参数使用逗号隔开,运行结果为3

以上代码运行结果为:

在这里插入图片描述

复习使用this实现继承

2.2.2 apply方法

apply 方法的用于与call 非常类似,区别在于,不能以参数列表的形式传递实参,必须以数组的形式传递

var o = {

name: ‘andy’

}

function fn(a, b) {

console.log(this);

console.log(a + b)

};

// 普通调用

fn(1, 2)

// call调用,将函数中的this修改为o对象

fn.call(o, 1, 2)

// apply 调用,区别在于参数列表必须以数组形式传递

fn.apply(o,[1,2])

可以看到,我们传入函数的实参是数组,但是函数内部会自动展开为参数列表

利用这一特性,我们可以结合 Math.max 方法求数组的最大值或者最小值

Math.max 方法可以求一组数字的最大值,语法如下

Math.max(1,2,3,4,5)

参数为参数列表形式

利用apply 可以将数组传入

var numbers = [3, 2, 44, 11, 66, 7]

var max=Math.max.apply(null,numbers)

console.log(max);

也可以利用 ES6 的 Spread syntax 语法

var max=Math.max(…numbers)

2.2.3 bind方法

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

bind() 方法不会调用函数,但是能改变函数内部this 指向

如果只是想改变 this 指向,并且不想调用这个函数的时候,可以使用bind

应用场景:不调用函数,但是还想改变this指向

var o = {

name: ‘andy’

};

function fn(a, b) {

console.log(this);

console.log(a + b);

};

var f = fn.bind(o, 1, 2); //此处的f是bind返回的新函数

f();//调用新函数 this指向的是对象o 参数使用逗号隔开

在这里插入图片描述

解惑

上面的代码

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() {
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后

分享一套阿里大牛整理的前端资料给大家,点击前端校招面试题精编解析大全即可获取

❤️ 谢谢支持,喜欢的话别忘了 关注、点赞哦。

标签,创建了三个定时器,3秒之后打印每个li标签元素内容

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

(function(i) {

setTimeout(function() {
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-saaYn8Sm-1712593959302)]

[外链图片转存中…(img-uyeUWWeT-1712593959302)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

[外链图片转存中…(img-fUwXoqRw-1712593959303)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后

分享一套阿里大牛整理的前端资料给大家,点击前端校招面试题精编解析大全即可获取

❤️ 谢谢支持,喜欢的话别忘了 关注、点赞哦。

前端校招面试题精编解析大全

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值