一 函数 参数默认值
1. 规则
(1)ES6 允许为函数的参数设置默认值: 在形参出直接定义即可, 不用关键字声明
- function ff(x, y = World) {
- console.log(x, y);
- }
- console.log(ff(Hello)); // Hello World
- console.log(ff(Hello, China)); // Hello China
- console.log(ff(Hello, )); // Hello
(2) 函数参数 在形参处默认声明: 规定 函数内不能用 let 或 const 再次声明, 否则会报错
- function foo(x = 5) {
- let x = 1; // error
- const x = 2; // error
- }
(3) 函数参数 设置默认值: 不会被记录到 函数. length 中
函数. length 用于获取形参个数
- (function (a) {}).length // 1
- (function (a = 5) {}).length // 0
- (function (a, b, c = 5) {}).length // 2
(4) 函数参数 设置默认值: 参数会在形参处 形成一个单独的作用域 (conext)
- var x = 1;
- function f(x, y = x) {
- console.log(y);
- }
- f(2) // 2
- let x = 1;
- function f(y = x) {
- let x = 2;
- console.log(y);
- }
- f() // 1
2. 函数参数 解构赋值
函数 参数为对象, 设置默认值
- function foo({
- x = 10,
- y = 5
- }) {
- console.log(x, y);
- }
- foo({}) // 10 5
- foo({x: 1}) // 1 5
- foo() // TypeError: Cannot read property x of undefined
- function foo({
- x = 10,
- y = 5
- } = {}) {
- console.log(x, y);
- }
- foo({}) // 10 5
- foo({x: 1}) // 1 5
- foo() // 1 5
- function foo({
- x = 10,
- y
- }) {
- console.log(x, y);
- }
- foo({}) // 10 undefined
- foo({x: 1}) // 1 undefined
- foo() // TypeError: Cannot read property x of undefined
重点区分
- // 写法一
- function m1({x = 0, y = 0} = {}) {
- return [x, y];
- }
- // 写法二
- function m2({x, y} = { x: 0, y: 0 }) {
- return [x, y];
- }
- // 函数没有参数的情况
- m1() // [0, 0]
- m2() // [0, 0]
- // x 和 y 都有值的情况
- m1({x: 3, y: 8}) // [3, 8]
- m2({x: 3, y: 8}) // [3, 8]
- // x 有值, y 无值的情况
- m1({x: 3}) // [3, 0]
- m2({x: 3}) // [3, undefined]
- // x 和 y 都无值的情况
- m1({}) // [0, 0];
- m2({}) // [undefined, undefined]
- m1({z: 3}) // [0, 0]
- m2({z: 3}) // [undefined, undefined]
- // 写法三
- function m3({x = 1, y = 0} = {}) {
- return [x, y];
- }
- // 写法四
- function m4({x = 1, y} = { x: 0, y: 0 }) {
- return [x, y];
- }
- m1() // [1, 0]
- m2() // [0, 0]
3. 函数参数默认值 的应用
应用一: 指定某一个参数, 不能省略
- function throwIfMissing() {
- throw new Error(Missing parameter);
- }
- function foo(mustBeProvided = throwIfMissing()) {
- return mustBeProvided;
- }
- foo()
- // Error: Missing parameter
应用二: 某一个参数可省略
function foo(optional = undefined) { ... }
二 函数 的 rest 参数
ES6 定义了 rest 参数, 用于获取函数的多余参数 (在不确定函数有多少个参数时, 最适用)
语法:
函数形参中 (...rest) , 在函数内部 变量 rest 是存储着多余参数的一个真数组
rest 只是一个变量, 可以为任意值
- function add(...values) {
- let sum = 0;
- for (var val of values) {
- sum += val;
- }
- return sum;
- }
- add(2, 5, 3) // 10
- add(2, 5, 3, 5) // 15
rest 参数 约束:
...rest 中包含的参数, 不计入 函数. length 中; 当然, 设置默认值的参数, 也不计入 函数. length 中
函数的 ...rest 参数必须作为函数的最后一个参数, 其后 不能再有其他参数 (否则 函数初始化时就会报错)
对比 ES5 中的 arguments:
arguments: 函数内部的一个属性, 存储着函数中 所有实参的伪数组; arguments 是固定值, 函数内部直接访问即可; 箭头函数中不再支持 arguments
rest: 函数中的一个参数, 存储着多余参数的一个真数组; rest 是个变量, 声明形参, 才能在函数中访问
三 箭头函数
1. 箭头函数 语法
箭头函数的 主要构成:
箭头函数 参数: 不需要参数 或 需要多个参数, 就使用 一个圆括号 代表参数部分
箭头函数 函数体: 函数体重 多于一条语句, 要使用 大括号 将它们括起来
箭头函数 返回值: 函数体中 多于一条语句, 且有返回值时 return 关键字不能省略
- var sum = (num1, num2) = >{
- return num1 + num2;
- }
最简化 的箭头函数 var f = v => v
省略了 参数圆括号代码块中括号 return 关键字
- var f = v = >v;
- // 等同于
- var f = function(v) {
- return v;
- };
2. 箭头函数 this 指向
声明: 箭头函数 内部没有 this 属性; 所以 箭头函数内 this 指向 外层代码块的 this
纠正:
ES5 语法中的函数, 看 this 指向时的原则: 谁调用了函数 this 就指向谁
ES6 语法中的函数, 分析 this 指向, 只要找到箭头函数外层 this 指向即可 (而不是看谁调用的函数)
- <script>
- const fn1 = {
- name: function() {
- console.log(this); // fn1
- }
- }
- fn1.name();
- const fn2 = {
- name: () = >{
- console.log(this); // window
- }
- }
- fn2.name();
- </script>
- <script>
- let box1 = document.getElementById(box1);
- box1.name = wangthis.name = zhang;
- box1.addEventListener(click,
- function() {
- console.log(this.name); // wang 因为是 dom 对象, 调用了回调函数
- });
- let box2 = document.getElementById(box2);
- box2.name = wangthis.name = zhang;
- box2.addEventListener(click, () = >{
- console.log(this.name); // zhang this. 指向外层的 this
- });
- </script>
借用方法 call apply bind , 不能改变 this 指向
- var a = 2;
- var obj = {
- a: 100
- };
- var fn1 = (a) = >{
- console.log(this.a);
- };
- var fn2 = function(a) {
- console.log(this.a);
- };
- fn1.call(obj); // 2
- fn2.call(obj); // 100
3. 箭头函数 的约束
箭头函数 不能当作 构造函数 (因为 自身没有 this 机制)
箭头函数内 不能使用 arguments 对象, 用 rest 参数代替
箭头函数 中没有 argumentssupernew.target 这是三个变量, 均指向外层函数 的变量
四 函数的 name 属性 被写入标准
函数的 name 属性, 早就被浏览器广泛支持, 但是直到 ES6, 才将其写入了标准
对比:
写入标准之前: 将 匿名函数 赋值给一个变量; 访问 函数. name 返回空字符串
写入标准之后: 将 匿名函数 赋值给一个变量; 访问 函数. name 返回 变量名
- const test = function baz() {};
- console.log(test.name); // ES5 输出:""console.log(test.name); // ES6 输出:"baz"
五 函数内 关于 严格模式的约束
ES2016 规定: 函数参数 如果使用了默认值解构赋值扩展运算符, 函数内部就不能显式设定为严格模式 (否则会报错)
原因猜想: (待证实) 可理解为函数式一个整体, 函数 执行的时候: 先执行函数参数, 然后再执行函数体; 函数执行到中间 发现语法 要遵循 严格模式, 就会报错
解决方案:
- // 方案一:
- use strict;
- function doSomething(a, b = a) {
- // code
- }
- // 方案二:
- const doSomething = (function() {
- use strict;
- return function(value = 42) {
- return value;
- };
- } ());
来源: http://www.bubuko.com/infodetail-2494270.html