所需工具:
JavaScript
聪明的大脑文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/12368.html
勤劳的双手文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/12368.html
文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/12368.html
注意:本站只提供教程,不提供任何成品+工具+软件链接,仅限用于学习和研究,禁止商业用途,未经允许禁止转载/分享等文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/12368.html
文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/12368.html
教程如下
一、函数增强
1.1 函数对象的属性
javascript中函数也是一个对象,那么对象中就可以有属性和方法。文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/12368.html
name:一个函数的名字我们可以通过name来访问
length:属性length用于返回函数参数的个数文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/12368.html
注意:rest参数是不参与参数的个数的文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/12368.html
[php]
var bar = function(m, n, ...others) {
}文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/12368.html
console.log(bar.length) // 2
[/php]文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/12368.html
1.2 arguments
arguments 是一个对应于传递给函数的参数的类数组(array-like)对象
注意:array-like意味着它不是一个数组类型,而是一个对象类型:
拥有数组的一些特性,比如说length,比如可以通过index索引来访问
没有数组的一些方法,比如filter、map等
arguments转数组
遍历arguments,添加到一个新数组中
调用数组slice函数的apply方法
[php]
[].slice.apply(arguments)
Array.prototype.slice.apply(arguments)
[/php]
ES6中的两个方法
Array.from
[…arguments]
特别注意:箭头函数不绑定arguments
在箭头函数中使用arguments会去上层作用域查找
[php]
function foo() {
var bar = () => {
console.log(arguments)
}
bar()
}
foo(111, 222) // Arguments(2) [111, 222, callee: , Symbol(Symbol.iterator): ]
[/php]
1.3 剩余rest参数
ES6中引用了rest parameter,可以将不定数量的参数放入到一个数组中:
如果最后一个参数是 ... 为前缀的,那么它会将剩余的参数放到该参数中,并且作为一个数组
[php]
function foo(num1, num2, ...otherNums) {
// otherNums数组
console.log(otherNums) // [111, 222, 333]
}
foo(20, 30, 111, 222, 333)
[/php]
那么剩余参数和arguments有什么区别呢?
剩余参数只包含那些没有对应形参的实参,而 arguments 对象包含了传给函数的所有实参
arguments对象不是一个真正的数组,而rest参数是一个真正的数组,可以进行数组的所有操作
arguments是早期的ECMAScript中为了方便去获取所有的参数提供的一个数据结构,而rest参数是ES6中提供并且希望以此来替代arguments的
注意:剩余参数必须放到最后一个位置,否则会报错
1.4 纯函数的使用
纯函数的概念:
确定的输入一定产生确定的输出
执行过程中不能副作用
副作用是指在执行一个函数时,除了返回函数值之外,还对调用函数产生了附加的影响,比如修改了全局变量,修改参数或者改变外部的存储
实际开发中应用:
React中就要求无论是函数还是class声明一个组件,这个组件都必须像纯函数一样,保护它们的props不被修改
没有必要每一个函数都是纯函数
数组的方法中slice就是一个纯函数,不会修改数组本身,而splice函数不是一个纯函数:
slice:slice截取数组时不会对原数组进行任何操作,而是生成一个新的数组
splice:splice截取数组, 会返回一个新的数组, 也会对原数组进行修改
1.5 柯里化的过程
什么是柯里化
只传递给函数一部分参数来调用它,让它返回一个函数去处理剩余的参数
两个案例:
logInfo
[php]
// 1.没有柯里化的时候做法
function logInfo(date, type, message) {
console.log(`时间:${date} 类型:${type} 内容:${message}`)
}
// // 打印日志
// logInfo("2022-06-01", "DEBUG", "修复界面搜索按钮点击的bug")
// // 又修复了一个bug
// logInfo("2022-06-01", "DEBUG", "修复了从服务器请求数据后展示的bug")
// logInfo("2022-06-01", "DEBUG", "修复了从服务器请求数据后展示的bug")
// logInfo("2022-06-01", "DEBUG", "修复了从服务器请求数据后展示的bug")
// logInfo("2022-06-01", "FEATURE", "增加了商品的过滤功能")
// 2.对函数进行柯里化: 柯里化函数的做法
// var logInfo = date => type => message => {
// console.log(`时间:${date} 类型:${type} 内容:${message}`)
// }
function logInfo(date) {
return function(type) {
return function(message) {
console.log(`时间:${date} 类型:${type} 内容:${message}`)
}
}
}
var logToday = logInfo("2022-06-01")
var logTodayDebug = logToday("DEBUG")
var logTodayFeature = logToday("FEATURE")
// 打印debug日志
logTodayDebug("修复了从服务器请求数据后展示的bug")
logTodayDebug("修复界面搜索按钮点击的bug")
logTodayDebug("修复界面搜索按钮点击的bug")
logTodayDebug("修复界面搜索按钮点击的bug")
logTodayDebug("修复界面搜索按钮点击的bug")
logTodayFeature("新建过滤功能")
logTodayFeature("新建搜索功能")
[/php]
makeAdder
[php]
function makeAdder(count) {
function add(num) {
return count + num
}
return add
}
// 1.数字和5相加
var adder5 = makeAdder(5)
adder5(10)
adder5(15)
adder5(18)
// 2.数组和10相加
var adder10 = makeAdder(10)
adder10(10)
adder10(16)
adder10(19)
[/php]
柯里化优势:
函数的职责单一
函数的参数复用
自动柯里化的函数封装
[php]
// 将一个普通函数转化成柯里化函数
function curried(fn) {
function curryFn(...args) {
// 传入的参数大于等于fn的需要的参数个数,直接执行fn函数
// 否则返回新的函数继续接收参数
if(args.length >= fn.length) {
return fn.apply(this, args)
} else {
// 返回新的函数并接收参数
return function(...newArgs) {
// 递归调用currFn,此处的参数为上一次传入的参数和之后传入的参数
return curryFn.apply(this, args.concat(newArgs))
}
}
}
return curryFn
}
[/php]
注意:函数柯里化性能并不高(使用到闭包,可能会导致内存泄露)
1.6 组合函数的使用
组合函数
多个函数组合在一起, 依次调用
封装组合函数
[php]
// 传入多个函数,自动的将多个函数组合在一起依次调用
function composeFn(...fns) {
var length = fns.length
// 边界判断
if (length <= 0) return
for (var fn of fns) {
if (typeof fn !== "function") {
throw new Error("Expected a function")
}
}
return function (...args) {
// 第一个函数可能传入多个参数
var result = fns[0].apply(this, args)
// 之后的函数依次调用
for (var i = 1; i < length; i++) {
result = fns[i].apply(this, [result])
}
return result
}
}
[/php]
二、额外知识
2.1 with
with语句 扩展一个语句的作用域链。
[php]
var obj = {
message: "Hello World"
}
with (obj) {
console.log(message) // Hello World
}
[/php]
不建议使用with语句,因为它可能是混淆错误和兼容性问题的根源
2.2 eval
内建函数 eval 允许执行一个代码字符串
eval是一个特殊的函数,它可以将传入的字符串当做javaScript代码来运行
eval会将最后一句执行语句的结果,作为返回值
[php]
var message = "Hello World"
var codeString = `var name = "kobe"; console.log(name); console.log(message); "abc";`
var result = eval(codeString)
console.log(result) // abc
[/php]
不建议在开发中使用eval:
eval代码的可读性非常的差(代码的可读性是高质量代码的重要原则)
eval是一个字符串,那么有可能在执行的过程中被刻意篡改,那么可能会造成被攻击的风险
eval的执行必须经过JavaScript解释器,不能被JavaScript引擎优化
2.3 严格模式
什么是严格模式
严格模式是一种具有限制性的JavaScript模式,从而使代码隐式的脱离了“懒散(sloppy)模式”
支持严格模式的浏览器在检测到代码中有严格模式时,会以更加严格的方式对代码进行检测和执行
严格模式对正常的JavaScript语义进行了一些限制:
严格模式通过抛出错误来消除一些原有的 静默(silent)错误
严格模式让js引擎在执行代码时可以进行更多的优化(不需要对一些特殊的语法进行处理)
严格模式禁用了在ECMAScript未来版本中可能会定义的一些语法
如何开启严格模式:
严格模式通过在文件或者函数开头使用 use strict 来开启
[php]
// 给整个script开启严格模式
"use strict"
// 给一个函数开启严格模式
function foo() {
"use strict"
}
[/php]
严格模式的限制:无法意外的创建全局变量
严格模式会使引起静默失败(silently fail,注:不报错也没有任何效果)的赋值操作抛出异常
严格模式下试图删除不可删除的属性
严格模式不允许函数参数有相同的名称
不允许0的八进制语法
在严格模式下,不允许使用with
在严格模式下,eval不再为上层引用变量
严格模式下,this绑定不会默认转成对象
[php]
"use strict"
// 1.不会意外创建全局变量
// function foo() {
// message = "Hello World"
// }
// foo()
// console.log(message) // 报错
// 2.发现静默错误
var obj = {
name: "kobe"
}
Object.defineProperty(obj, "name", {
writable: false,
configurable: false
})
// obj.name = "curry"
console.log(obj.name)
// delete obj.name
console.log(obj)
// 3.参数名称不能相同
// function foo(num, num) {
// }
// 4.不能以0开头
// console.log(0o123) // 0o是ES6新语法可以写
// 5.eval函数不能为上层创建变量
// eval(`var message = "Hello World"`)
// console.log(message)
// 6.严格模式下, this是不会转成对象类型的
function foo() {
console.log(this)
}
foo.apply("abc")
foo.apply(123)
foo.apply(undefined)
foo.apply(null)
// 独立函数执行默认模式下, 绑定window对象
// 在严格模式下, 不绑定全局对象而是undefined
foo()
[/php]
评论