带你学习javascript的函数进阶(二)
2020/3/3 11:01:59
本文主要是介绍带你学习javascript的函数进阶(二),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1 严格模式
1.1 什么是严格模式
JavaScript除了提供正常模式外,还提供了严格模式(strict mode)。ES5的严格模式是采用具有限制性Javascript变体的一种方式。即在严格的条件下运行js代码。
严格模式在IE10以上版本的浏览器中才会被支持,旧版本浏览器会被忽略。
严格模式对正常的javascript语义做了一些更改:
- 消除了Javascrip语法的一些不合理、不严谨之处,减少了一些怪异行为。
- 消除了代码运行的一些不安全之处,保证代码运行的安全。
- 提高编译器效率,增加运行速度。
- 禁用了在ECMAScript的未来版本中可能会定义的一些语法,为未来新版本的Javascript做好铺垫。比
如一些保留字:class,enum,export,extends,import,super不能做变量。
1.2 开启严格模式
严格模式可以应用到整个脚本或个别函数中。因此在使用时,我们可以将严格模式分为脚本开启严格模式和
为函数开启严格模式两种情况
- 为脚本整个脚本开启严格模式
为整个脚步文件开启严格模式,需要在所有语句之前做一个特定语句"use strict"
<scirpt> "use strict" console.log("这是最严格模式") </scirpt> 复制代码
- 为函数开启严格模式
要给某个函数开启严格模式,需要把"use strict";(或'use strict')声明放在函数体所有语句前。
<script> function fn() { 'use strict' //下面的代码按照严格模式进行 } </script> 复制代码
3.3 严格模式中的变化
严格模式对javascript的语
法和行为,都做了一些改变
- 变量规定
- 在正常模式中,如果一个变量没有声明就赋值,默认的事全局变量。
- var 命令声明,然后再使用
<script> ‘use strict’ num = 10 console.log(num) </script> 复制代码
效果如下图
严禁删除已经声明的变量。
- 严格模式下this指向问题
- 以前在全局作用域函数中的this指向window对象。
- 严格模式下全局作用域中函数中的this事undefined。
- 以前构造函数时不加new也可以调用,当普通函数,this指向全局对象。
- 严格模式下,如果构造函数不加new调用,this会报错。 new实例化的构造函数指向创建的对象实例。
- 严格模式下,定时器里的this指向还是window.
- 严格模式下,事件、对象还是指向调用者。
- 函数变化
2 高阶函数
高阶函数是对其他函数进行操作的函数,它接收函数作为参数或函数作为返回值输出。
function fn(callback) { callback && callback() } fn(function(){ alert('lanfeng') }) 复制代码
function fn() { return function() { } } fn() 复制代码
此时fn就是一个高阶函数
函数也是一种数据类型,同样可以作为参数,传递给另外一个参数使用,最典型的就是作为回调函数
3 闭包
3.1 变量作用域
变量根据作用域的不同分为两种:全局变量和局部变量。
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 闭包案例
- 循环注册点击事件
//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) } 复制代码
- 循环中的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) } 复制代码
- 计算打车价格
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 闭包总结
- 闭包是什么?
闭包就是一个函数(一个作用域可以访问另外一个函数的局部变量)
- 闭包的作用是什么?
延伸变量的作用范围
4 递归
4.1 什么是递归
如果一个函数在内部可以调用其本身,那么这个函数就是递归函数。
递归函数的作用和循环效果一样
由于递归很容易发生“栈溢出”(stack overflow),所以必须要加退出条件 return
4.2 利用递归求数学题
- 求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 浅拷贝和深拷贝
- 浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用。
- 深拷贝拷贝多层,每一级别的数据都会拷贝。
- 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) 复制代码
//深拷贝,应用递归的方法 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) 复制代码
总结
本篇文章主要分享了函数的严格模式、高阶函数、闭包、递归、深拷贝、浅拷贝等知识点的用法及应用。如果想了解更多,请扫描二维码
这篇关于带你学习javascript的函数进阶(二)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-10-05小米13T Pro系统合集:性能与摄影的极致融合,值得你升级的系统ROM
- 2024-10-01基于Python+Vue开发的医院门诊预约挂号系统
- 2024-10-01基于Python+Vue开发的旅游景区管理系统
- 2024-10-01RestfulAPI入门指南:打造简单易懂的API接口
- 2024-10-01初学者指南:了解和使用Server Action
- 2024-10-01Server Component入门指南:搭建与配置详解
- 2024-10-01React 中使用 useRequest 实现数据请求
- 2024-10-01使用 golang 将ETH账户的资产平均分散到其他账户
- 2024-10-01JWT用户校验课程:从入门到实践
- 2024-10-01Server Component课程入门指南