带你学习javascript的函数进阶(二)

叫我詹躲躲 2020-11-06 20:37:31
学习 函数 javascript 进阶 带你


上一篇文章分享了《带你学习Javascript中的函数进阶(一)》,今天继续学习javascript的函数进阶的内容。


1 严格模式

1.1 什么是严格模式

JavaScript除了提供正常模式外,还提供了严格模式(strict mode)。ES5的严格模式是采用具有限制性Javascript变体的一种方式。即在严格的条件下运行js代码。
严格模式在IE10以上版本的浏览器中才会被支持,旧版本浏览器会被忽略。
严格模式对正常的javascript语义做了一些更改:

  1. 消除了Javascrip语法的一些不合理、不严谨之处,减少了一些怪异行为。
  2. 消除了代码运行的一些不安全之处,保证代码运行的安全。
  3. 提高编译器效率,增加运行速度。
  4. 禁用了在ECMAScript的未来版本中可能会定义的一些语法,为未来新版本的Javascript做好铺垫。比

如一些保留字:class,enum,export,extends,import,super不能做变量。

1.2 开启严格模式

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

  1. 为脚本整个脚本开启严格模式

为整个脚步文件开启严格模式,需要在所有语句之前做一个特定语句"use strict"

<scirpt>
"use strict"
console.log("这是最严格模式")
</scirpt>
  1. 为函数开启严格模式

要给某个函数开启严格模式,需要把"use strict";(或’use strict’)声明放在函数体所有语句前。

<script>
function fn() {

'use strict' //下面的代码按照严格模式进行
}
</script>

3.3 严格模式中的变化

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

  1. 变量规定
  • 在正常模式中,如果一个变量没有声明就赋值,默认的事全局变量。
  • var 命令声明,然后再使用
<script>
‘use strict’
num = 10
console.log(num)
</script>

效果如下图
image.png
严禁删除已经声明的变量。

  1. 严格模式下this指向问题
  • 以前在全局作用域函数中的this指向window对象。
  • 严格模式下全局作用域中函数中的this事undefined。
  • 以前构造函数时不加new也可以调用,当普通函数,this指向全局对象。
  • 严格模式下,如果构造函数不加new调用,this会报错。 new实例化的构造函数指向创建的对象实例。
  • 严格模式下,定时器里的this指向还是window.
  • 严格模式下,事件、对象还是指向调用者。
  1. 函数变化
  • 严格模式下函数不能有重名的参数
  • 函数必须声明在顶层,新版本的js会引入“块级作用域”(ES6中已引入)。为了与新版本接轨,不允许在非函数的代码块内声明函数,如在if,for语句中声明函数。

2 高阶函数

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

function fn(callback) {

callback && callback()
}
fn(function(){

alert('lanfeng')
})
function fn() {

return function() {

}
}
fn()

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

3 闭包

3.1 变量作用域

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

  1. 函数内部可以使用全局变量
  2. 函数外部不可以使用局部变量
  3. 当函数执行完时,本作用域内的局部变量会被销毁。

3.2 什么是闭包

闭包指有权访问另外一个函数作用域中变量的函数。也就是说,一个作用域可以访问另外一个函数内部的局部变量。

//fn 外面的作用域可以访问fn内部的局部变量
function fn() {

var num = 10
function fun () {

console.log(num) //可以访问num
}
return fun
}
var f = fn()
f() //10
//fn 外面的作用域可以访问fn内部的局部变量
function fn() {

var num = 10
// 返回一个匿名函数
return function() {

console.log(num) //可以访问num
}
}
var f = fn()
f() //10

闭包的主要作用: 延伸了变量的作用范围

3.3 闭包案例

  1. 循环注册点击事件
//html
<ul class="nav">
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
</ul>
//js
//点击li输出当前li的索引
//利用动态田径属性方式
var lis = document.querySelector('.nav').querySelectorAll('li')
for(var i=0 ;i<lis.length; i++) {

lis.index = i
lis[i].onclick = function() {

console.log(this.index)
}
}
//利用闭包的方式
var lis = document.querySelector('.nav').querySelectorAll('li')
for(var i=0 ;i<lis.length; i++) {

(function(i) {

lis[i].onclick = function() {

console.log(i)
}
})(i)
}
  1. 循环中的setTimeout()
//html
<ul class="nav">
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
</ul>
//js
//利用闭包
var lis = document.querySelector('.nav').querySelectorAll('li')
for(var i=0 ;i<lis.length; i++) {

(function(i){

setTimeout(function() {

console.log(lis[i].innerHTML)
},3000)
})(i)
}
  1. 计算打车价格
var car =function() {

var start = 13;
var total = 0;
return {

//正常价格
price: function(n) {

if(n <= 3) {

total = start
} else {

total = start + (n-3)* 5
}
return total;
},
// 拥堵之后
yd: function(flag) {

flag? total+ 10 :total
}
}
}()
console.log(car.price(5))
console.log(car.yd(true))

3.4 闭包总结

  1. 闭包是什么?

闭包就是一个函数(一个作用域可以访问另外一个函数的局部变量)

  1. 闭包的作用是什么?

延伸变量的作用范围

4 递归

4.1 什么是递归

如果一个函数在内部可以调用其本身,那么这个函数就是递归函数。
递归函数的作用和循环效果一样
由于递归很容易发生“栈溢出”(stack overflow),所以必须要加退出条件 return

4.2 利用递归求数学题

  1. 求123…*n
function fn(n) {

if(n = 1) {

return 1
}
return n * fn(n-1)
}
console.log(fn(3)) // 6

4.3 利用递归求:根据id返回对应的数据对象

var data = [{

id:1,
name:'家电',
goods: [
{

id: 11,
gname: '冰箱'
},
{

id: 12,
gname: '洗衣机'
}
]
},
{

id: 2,
name: '服饰'
}
]
function getObj(arr, id) {

var o = {
}
arr.forEach(function(item){

if(item.id === id) {

o= item
} else if(item.goods && item.goods.length>0) {

o =getObj(item.goods, id);
}
})
return o
}
console.log(getObj(data, 1))

5 递归

5.1 浅拷贝和深拷贝

  1. 浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用。
  2. 深拷贝拷贝多层,每一级别的数据都会拷贝。
  3. Object.assign(target, …sources) es6新增方法可以浅拷贝
var obj = {

id: 1,
name: 'andy',
msg: {

age: 18
}
}
var o = {
}
for(var k in obj) {

// k是属性名
o[k] = obj[k]
}
console.log(o)
o.msg.age = 20
console.log(obj) //obj发生变化
//用es6语法糖
Object.assign(o, obj)

image.png

//深拷贝,应用递归的方法
function deepCopy(newObj, oldObj) {

for(var k in oldObj) {

//判断我们的属性值属于哪种类型
var item = oldObj[k]
// 判断是否是数组
if(item instanceof Array) {

newObj[k] = []
deepCopy(newObj[k], item)
} else if(item instanceof Object) {

//判断是否是对象
newObj[k] = {
}
deepCopy(newObj[k], item)
} else {
 // 属于简单数据类型
newObj[k] = item
}
}
}
deepCopy(o,obj)
console.log(o)

总结

本篇文章主要分享了函数的严格模式、高阶函数、闭包、递归、深拷贝、浅拷贝等知识点的用法及应用。

版权声明
本文为[叫我詹躲躲]所创,转载请带上原文链接,感谢
https://my.oschina.net/u/3995971/blog/4558943

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云