带你学习javascript的函数进阶(二)
上一篇文章分享了《带你学习Javascript中的函数进阶(一)》,今天继续学习javascript的函数进阶的内容。
文章目录
- 1 严格模式
- 1.1 什么是严格模式
- 1.2 开启严格模式
- 3.3 严格模式中的变化
- 2 高阶函数
- 3 闭包
- 3.1 变量作用域
- 3.2 什么是闭包
- 3.3 闭包案例
- 3.4 闭包总结
- 4 递归
- 4.1 什么是递归
- 4.2 利用递归求数学题
- 4.3 利用递归求:根据id返回对应的数据对象
- 5 递归
- 5.1 浅拷贝和深拷贝
- 总结
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 = 10console.log(num)</script>
效果如下图
严禁删除已经声明的变量。
- 严格模式下this指向问题
- 以前在全局作用域函数中的this指向window对象。
- 严格模式下全局作用域中函数中的this事undefined。
- 以前构造函数时不加new也可以调用,当普通函数,this指向全局对象。
- 严格模式下,如果构造函数不加new调用,this会报错。 new实例化的构造函数指向创建的对象实例。
- 严格模式下,定时器里的this指向还是window.
- 严格模式下,事件、对象还是指向调用者。
- 函数变化
- 严格模式下函数不能有重名的参数
- 函数必须声明在顶层,新版本的js会引入“块级作用域”(ES6中已引入)。为了与新版本接轨,不允许在非函数的代码块内声明函数,如在if,for语句中声明函数。
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 = 10function 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 = ilis[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的函数进阶(二)相关推荐
- 零基础带你学习MySQL—日期函数(十五)
零基础带你学习MySQL-日期函数(十五) 一.CURRENT_DATE ( ) 当前日期 二.CURRENT_TIME() 当前时间 三.CURRENT_TIMESTAMP()当前时间戳 四.练习
- 零基础带你学习MySQL—unique 唯一(二十五)
零基础带你学习MySQL-unique 唯一(二十五) unqiue 使用细节 如果没有指定 not null 则 unique 字段可以有多个 null 如果一个列(字段) 是 unique not ...
- 零基础带你学习MySQL—加密函数和系统函数(十六)
零基础带你学习MySQL-加密函数和系统函数(十六)
- 零基础带你学习MySQL—数学函数(十四)
零基础带你学习MySQL-数学函数(十四)
- 零基础带你学习MySQL—查询数据库(二)
零基础带你学习MySQL-查询数据库(二) 如果数据库名字不是关键字,习惯性的不加反引号 哎呀 我就是懒,如果是关键字,必须要加上反引号 什么是关键字 我想大家应该都知道 我就不写了 哎呀 我就是懒
- 带你学习Javascript中的函数进阶(一)
文章目录 1. 函数的定义和调用 1.1 函数的定义方式 1.2 函数的调用方式 2. this 2.1 函数内this的指向 2.2 改变函数内部this指向 2.3 call apply bind ...
- JS进阶学习(作用域、函数进阶、解构赋值、原型链)
文章目录 1.面相对象编程介绍 2.ES6中的类和对象 3.类的继承 ES6中的类和对象 三个注意点 作用域 局部作用域 全局作用域 作用域链 JS垃圾回收机制(GC) JS垃圾回收机制-算法说明 闭 ...
- Python学习笔记---day12函数进阶
day12函数进阶 函数的嵌套 闭包 装饰器 上述内容均属于函数部分必备知识,以后开发时直接和间接都会使用,请务必理解(重在理解,不要去死记硬背). 1. 函数嵌套 Python中以函数为作用域,在作 ...
- Python学习 Day28 JS函数(二)
JS函数(二) (一)return关键字 关键字return一般结合函数一起使用.而且需要注意,这个关键字一般只能在函数体中使用 作用: 1.函数体中如果遇见关键字return,函数体后面语句不再执行 ...
最新文章
- 为什么很多 SpringBoot 开发者放弃了 Tomcat,选择了 Undertow?
- Linux中vi编辑器的使用详解
- (转)PWA(Progressive Web App)渐进式Web应用程序
- 解决WINCE6.0新建工程编译出错的问题
- markdown流程图多分支_提高生产力的好工具MarkDown语法学习
- 逆向分析使用COM组件对象模型的代码
- python通讯录管理程序的用户可行性_通讯录管理系统项目可行性分析
- MyBatis中增删改操作
- 小程序 坚屏_如何构建坚如磐石的应用程序
- 原子微型结构信息应用到局部图形信息存储的猜想
- Angular属性型指令
- 学习是第一生产力——学习型组织众书读后感
- 一次系统调用开销到底有多大?strace、time、perf命令
- linux nfs 多个ip,linux基础之NFS
- js css自动幻灯片切换,纯js和CSS3炫酷自动幻灯片特效
- iOS oc对网络图片进行黑白化处理
- 图像处理之双线性插值法
- Android 引入recycleview依赖报错INFO: Configuration ‘compile‘ is obsolete and has been replaced with ‘imple
- 文华财经wh6如何导入需要的指标
- 国际标准化比率 INR