javaScript 严格模式 高阶函数 闭包
2020年7月14日javaScript 除了提供正常模式外,还提供了严格模式(strict mode) . es5 的严格模式是采用具有限制性javaScript变体的一种方式,即在严格的条件下运行js代码.
严格模式在IE10以上的浏览器中才会被支持,旧版本浏览器中会被忽略,严格模式对正常的javaScript语义做了一些修改
- 消除了javaScript语法的一些不合理,不严谨支持,减少一些怪异行为
- 消除代码运行的一些不安全之处,班长代码运行安全
- 调高编译效率,增加运行速度
- 禁用了在ECMAScript的未来版本中可能会定义的一些语法,未来新版本的javaScript做好铺垫.比如一些保留字如:class enum export extends import super 不能作为变量名
开启严格模式
严格模式可以应用到整个脚本或个别函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<!-- 为整个脚本开严格模式 --> <script> 'use strict' . . . </script> //为一个方法开启严格模式 function fn() { 'use strict' } //为只执行函数添加严格模式 ;(function(){ 'use strict' })(); |
严格模式下注意细节
- 严格模式下 : 变量必须先声明在使用
- 严格模式下 : 变量不可以删除
delete num
- 严格模式下 : 全局作用域函数指向 undefined ,普通模式下是window
- 严格模式下 : 构造函数不可以像普通函数一样调用,因为以前this是指向window,普通调用会给window添加属性和方法, 所以必须这样调用
new Star()
- 函数不能有重名形参
- 函数声明必须在顶层,不允许在非函数的代码块内声明,
更多规则请查看 https://developer.mozilla.org/zh-CN/docs/Web/javaScript/Reference/Strict_mode
高阶函数
高阶函数是对其他函数进行的操作函数,它接收函数作为参数或将函数作为返回值输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
/** * 接收一个函数 * @param callback */ function fn(callback) { callback&&callback() } fn(function(){alert(1)}) /** * 返回一个函数 * @returns {function(...[*]=)} */ function fun (){ return function(){console.log(11)} } var newFun = fun(); //或者在后面再加一个() 直接调用接收的函数 newFun() //执行这个接收的函数 |
闭包
主要作用延伸变量作用范围
闭包(closure): 指有权访问 , 另一个函数作用域中 , 变量的函数 — JavaScript 高级设计
1 2 3 4 5 6 7 8 9 10 11 12 |
//简单闭包函数 function fn1() { var num = 10 function fn2() { console.log(num) } fn2() } fn1() |
1 2 3 4 5 6 7 8 9 10 11 |
//简单闭包函数 function fn1() { var num = 10 return function () { console.log(num) } } var fn2 = fn1() fn2() //这个函数和可以使用局部变量num ,延伸变量作用范围 |
闭包小案例 面试常考
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul> <script> var lis = document.querySelectorAll('li') lis.forEach(function (value, index) { ;(function(value){ value.onclick = function(){ console.log(value.innerText) } })(value); }) </script> </body> </html> |
闭包小案例 延迟三秒打印所有li的内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <ul> <li>茕茕孑立</li> <li>沆瀣一气</li> <li>踽踽独行</li> <li>醍醐灌顶</li> </ul> <body> <script> var lis = document.querySelectorAll('ul li') lis.forEach(function (value, index) { ;(function () { setTimeout(function () { console.log(value.innerHTML) }, 3000) })(value); }) </script> </body> </html> |
闭包小案例 出租车计价
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
var car = (function () { var start = 13 var total = 0 return { price: function (n) { if (n <= 3) { return total = start } else { return total = start * (n - 3) * 5 } }, dy: function (flag) { return flag ? total + 10 : total } } })(); console.log(car.price(3)) console.log(car.dy(3)) |
闭包思考题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
var name = 'The Window'; var object = { name: 'My Object', getName: function () { /** * 返回的是一个匿名函数 * 匿名函数this指向window */ return function () { return this.name } } } var name1 = 'The Window'; var object1 = { name1: 'My Object', getName: function () { var _this = this; /** * 返回的是一个匿名函数 * _this 指向 上一个变量 */ return function () { return _this.name1 } } } console.log(object.getName()()) console.log(object1.getName()()) |
递归
简单递归函数
1 2 3 4 5 6 7 8 9 10 11 12 |
var num = 1 function fun() { console.log('1') if (num == 6) { return; } num++ fun() } fun() |
利用递归求1~n 的阶乘 1*2*3*4
1 2 3 4 5 6 7 |
function fun(n) { if (n == 1) { return 1; } return n * fun(n - 1) } console.log(fun(10)) |
利用递归求 斐波那契数列 不知道是什么东西
1 2 3 4 5 6 7 |
function fu(n) { if (n === 1 || n === 2) { return 1; } return fu(n - 1) + fu(n - 2) } console.log(fu(25)) |
利用递归函数写 3级查找
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
obj = [ { id: 1, goods: [ {id: 6} ] }, { id: 2, goods: [ {id: 4}, {id: 5} ] } ] var o = {}; function getID(json, id) { json.forEach(function (value, index) { if (value.id === id) { o = value } else if (value.goods && value.goods.length > 0) { getID(value.goods, id) } }) return o; } console.log(getID(obj, 4)) |
浅拷贝 和 深度拷贝
递归就是函数自己调用自己,并加上停止条件
浅拷贝
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
var obj = { id: 1, name: 'ldh' } var o = {} //使用for in 遍历 obj 使用源码浅拷贝 for (var k in obj) { /** *给o对象创建 属性 *并且切将obj的值赋值过来 */ o[k] = obj[k] } |
javaScript自带浅拷贝的方法
1 2 3 4 5 6 7 8 9 10 11 |
var obj = { id: 1, name: 'ldh' } var o = {} /** * o : 复制到那个对象 * obj : 有数据的对象 */ Object.assign(o,obj) |
利用递归写深拷贝
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
var obj = { arr: ['123', '234'], obj: {'fd': 'wer', 'asdf': 'asdf'} } var zf = {} 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(zf,obj) zf.arr[0] = 11111111111 console.log(zf) console.log(obj) |