JavaScript高级 函数增强
一、函数属性和arguments
函数属性
默认函数对象中已经有的属性。
- name
- length
|
|
arguments
一个对应于传递给函数的参数的类数组(array-like)对象。
|
|
array-like意味着它不是一个数组类型,而是对象类型。
- 但是它有数组的一些特性,比如length,比如可以通过index索引访问
- 但是没有数组的方法,比如filter,map
argument转数组,以便使用数组的特性:
- Array.from
- […arguments]
- [].slice.apply(arguments)
剩余参数(rest)
es6中引用了rest parameter,可以将不定数量的参数放到一个数组中。
如果最后一个参数是 … 为前缀的,那么它会将剩余的参数放到该参数中,并且作为一个数组。
注意:剩余参数需要写到其他参数的最后。
|
|
剩余参数和argument的区别:
- 剩余参数只包含那些没有对应形参的实参,而arguments对象包含了传给函数的所有实参
- arguments对象不是一个真正的数组,而rest参数是一个真正的数组,可以进行数组的所有操作
- arguments是早期ecmascript中为了方便去获取所有的参数提供的一个数据结构,而rest参数是es6中提供并且希望以此来替代arguments的
二、纯函数的理解和应用
确定的输入,一定会产出生确定的输出。
函数在执行过程中,不能产生副作用。
|
|
三、柯里化的理解和应用
|
|
自动柯里化函数:
|
|
四、组合函数理解和应用
组合函数是在JavaScript开发过程中对函数使用的一种技巧,模式:
- 比如现在需要对某一个数据进行函数的调用,执行两个函数fn1和fn2,这两个函数是依次执行的
- 那么如果每次都需要进行两个函数的调用,操作上就会显得重复
- 那么可以将这两个函数组合起来,自动依次调用
- 这个过程就是对函数的组合,称之为组合函数
|
|
自动组合函数:
|
|
五、with,eval的使用
with语句
扩展一个语句的作用域链
|
|
不建议使用with语句,以为它可能是混淆错误和兼容性问题的根源.
eval函数
运行执行一个代码字符串。
-
eval是一个特殊的函数,它可以将传入的字符串当作JavaScript代码来执行
-
eval会将最后一行执行语句的结果,作为返回值
|
|
不建议在开发中使用eval:
- eval代码的可读性非常差(代码的可读性是高质量代码的重要原则)
- eval是一个字符串,那么有可能在执行的过程中被刻意篡改,造成被攻击的风险
- eval的执行必须经过JavaScript解释器,不能被JavaScript引擎优化
六、严格模式的使用
JavaScript历史的局限性:
- 长久以来,JavaScript不断向前发展并且未带来任何兼容性问题
- 新的特性被加入,旧的功能也没有改变,这么做有利于兼容旧代码
- 但缺点是JavaScript创造者的任何错误或不完善的决定也将永远被保留在JavaScript语言中
在ECMAScript5标准中,JavaScript提出了严格模式的概念(Strict Mode)
- 严格模式很好理解,是一种具有限制性的JavaScript模式,从而使代码隐式的脱离了“懒散(sloppy)模式”
- 支持严格模式的浏览器在检测到代码中有严格模式时,会以更加严格的方式对代码进行检测和执行
严格模式对正常的JavaScript语义进行了一些限制:
- 严格模式通过抛出错误来消除一些静默错误
- 严格模式让JS引擎在执行代码时可以进行更多的优化(不需要对一些特殊的语法进行处理)
- 严格模式禁用了在ECMAScript未来版本中可能会定义的一些语法
开启严格模式
-
可以支持在js文件中开启严格模式
1 2 3 4
// javascript文件 "use strict" console.log(name)
-
也支持对某一个函数开启严格模式
1 2 3 4 5 6 7 8
function foo() { "use strict" m = "foo" console.log(m) } foo()
注意:
- 没有类似于 “no use strict"这样的指令也可使程序返回默认模式
- 现代JavaScript支持 “class” 和 “module”,它们会自动启用use strict
严格模式的语法限制:
JavaScript被设计未新手开发者更容易上手,所以有时候本来错误语法,被认为也是可以正常被解析的
但是这种方式可能会带来安全隐患
在严格模式下,这种失误就会被当作错误,以便可以快速的发现和修正
-
无法意外的创建全局变量
1 2 3 4 5 6 7 8 9
"use strict" function foo() { message = "hello message" } foo() console.log(message) // ReferenceError: message is not defined
-
严格模式会使引起静默失败的赋值操作抛出异常(silently fail,不报错也没有任何效果)
1 2 3 4 5 6 7 8 9 10 11 12 13
'use strict' var obj = { name: 'mocha' } Object.defineProperty(obj, 'name', { configurable: false }) delete obj.name // 非严格模式下,此步不报错也没有任何效果,继续执行下一步;严格模式下抛出错误 console.log(obj.name)
-
严格模式下试图删除不可删除的属性
1 2 3 4 5 6 7 8 9 10 11 12 13
"use strict" var obj = { name: "mocha" } Object.defineProperty(obj, "name", { writable: false }) obj.name = "latte" console.log(obj.name)
-
严格模式不允许函数参数有相同的名称
1 2 3
"use strict" function foo(num, num) {}
-
不允许0的八进制语法
1 2 3
"use strict" console.log(0o123)
-
不允许使用with
-
eval不再为上层引用变量
1 2 3 4 5
"use strict" eval(`var message = "hello message"`) console.log(message) // ReferenceError: message is not defined
-
this绑定不会默认转成对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14
"use strict" function foo() { console.log(this) } foo.apply("abc") // abc foo.apply(123) // 123 foo.apply(undefined) // undefined foo.apply(null) // null // 独立函数调用时,绑定window对象 // 严格模式下,不绑定全局对象而是绑定undefined foo() // undefined
- 原文作者:Gmi_61
- 原文链接:https://www.huangzhishou.com/post/JavaScript%E9%AB%98%E7%BA%A7-%E5%87%BD%E6%95%B0%E5%A2%9E%E5%BC%BA.html
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。