函数默认参数

function test(x = 1, y = 2) {
return x + y
}
test(5, 6) //
test() //

若默认参数在必须参数之前,要想取得默认参数,只有当传入的值为undefined才能取到

function test(x = 1, y) {
console.log(x,y)
}
test(5, 6) //5,6
test(1) //3 undefined
test(null,1) //null 1
test(undefined,1) //1,1

参数默认值是惰性求值

let x = 99;
//每次调用函数,默认值x+1都会重新计算,而不是默认等于100
function foo(p = x + 1) {
console.log(p)
}
foo() //
x = 105;
foo() //

解构赋值与默认值联合使用

function test({x,y=5}={}){
console.log(x,y)
}
test({x:2,y:6}) //2 6
test({}) //undefined 5

上面代码:如果没有传参数,优先使用默认值,若没有默认值,再使用解构赋值

函数的length属性length属性的含义是,该函数预期传入的参数个数。指定了默认值以后,函数的length属性,将返回没有指定默认值的参数个数。)

(function (a) {}).length //
(function (a = 5) {}).length //
(function (a, b, c = 5) {}).length //

作用域(一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域(context)。等到初始化结束,这个作用域就会消失。这种语法行为,在不设置参数默认值时,是不会出现的。)

var x = 1;
var z = 2;
//函数默认参数的变量优先取函数参数内向同名称变量的值,若函数参数内部存在同名变量,则取父及变量
function f(x, y = x, m = z) {
console.log(y);
console.log(m)
} f(2) // 2 2

rest参数( rest 参数(形式为...变量名),用于获取函数的多余参数。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。)

function add(...values) {
let sum = 0;
for (var val of values) {
sum += val;
}
return sum;
} add(2, 5, 3) //

rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错

//error
function f(a, ...b, c) {
// ...
}

严格模式(函数内可以使用严格模式,但是只要函数参数使用了默认值、解构赋值、或者扩展运算符,就不能在函数内使用严格模式)

function doSomething(a, b) {
'use strict';
// code
}

可以使用全局声明严格模式或把函数包裹在一个无参数的立即执行的函数里可以规避严格模式的限制

'use strict';

function doSomething(a, b = a) {
// code
}
const doSomething = (function () {
'use strict';
return function(value = 42) {
return value;
};
}());

name属性(返回函数名)

var f = function(){}
f.name; //f
function test(){}
test.name //test

箭头函数

var f = v => v;
//相当于
var f = function (v) {
return v
}

对于没有参数或有多个参数的箭头函数,参数部分用括号括起来。如果返回的代码块部分多以一条语句,也要用括号括起来且必须使用return语句

var f = () => 5
f(); //
var fn = (x, y) => x + y
fn(2, 3) //
var f = ()=>{
console.log("hello,ES6");
return 2;
}
f() //hello,ES6 2

如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。

// 报错
let getTempItem = id => { id: id, name: "Temp" }; // 不报错
let getTempItem = id => ({ id: id, name: "Temp" });

使用箭头函数请注意:

(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。

(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。

function foo() {
setTimeout(() => {
console.log('id:', this.id);
}, 100);
} var id = 21; foo.call({ id: 42 });
// id: 42

尾调用及尾调用优化

  • 尾调用(某个函数的最后一步是调用另一个函数)
function f(x){
return g(x);
}  //注意这里一定要写return才能表示尾调用
  • 尾调用优化(只保留内层函数的调用帧,注意:只有内层函数不再用到外部函数的变量时才能用尾调用优化)
function f() {
let m = 1;
let n = 2;
return g(m + n);
}
f(); // 等同于
function f() {
return g(3);
}
f(); // 等同于
g(3);

尾递归(函数调用自身,称为递归。如果尾调用自身,就称为尾递归)

//普通递归函数,容易发生栈溢出
function factorial(n) {
if (n === 1) return 1;
return n * factorial(n - 1);
}
factorial(5) //
//尾递归函数,内存中永远只保留最后一帧,永远不会发生栈溢出
function factorialV2(n, total) {
if (n === 1) return total;
return factorialV2(n - 1, n * total)
}
factorialV2(5, 1) //

尾递归的调用方式优化(使用默认参数或者再使用另外一个函数包裹)

function factorialV2(n, total = 1) {
if (n === 1) return total;
return factorialV2(n - 1, n * total)
} function factorial(n){
return factorialV2(n, 1)
} factorialV2(5) //

最新文章

  1. CSS 3学习——边框
  2. mysql 5分钟倒计时
  3. mysql提供dataprovider
  4. Java实现JDBC连接数据库实例
  5. 2、CC2541芯片中级教程-OSAL操作系统(进一步了解-OLED && 普通按键和5方向按键-中断!!!)这个系统驱动层和应用层不一样~
  6. python+php+redis+shell实现几台redis的同步数据
  7. 树--四分树(UVa297)
  8. IOS 播放动态Gif图片
  9. 【HDOJ】2444 The Accomodation of Students
  10. INSERTION_SORT插入排序C++实现
  11. 省市区三级联动插件:app-jquery-cityselect.js
  12. awk练习题
  13. loj#6074. 「2017 山东一轮集训 Day6」子序列(矩阵乘法 dp)
  14. SQL SERVER数据库附加是只读的解决方法
  15. 自建yum仓库,分别为网络源和本地源
  16. javascript 重要属性之prototype(继承)
  17. Luogu P3321 [SDOI2015]序列统计
  18. 【UOJ#422】【集训队作业2018】小Z的礼物(min-max容斥,轮廓线dp)
  19. windows 安装mongodb
  20. 漫谈可视化Prefuse(六)

热门文章

  1. sublime 快捷键,左菜单乱码
  2. PHP 提高PHP性能的编码技巧以及性能优化
  3. python元组和列表区别
  4. Swap file "/etc/.hosts.swp" already exists! [O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it,
  5. oracle字符串函数总结
  6. PAT 天梯赛 L2-012. 关于堆的判断 【Heap】【STL】
  7. python3 内置常用函数系列一
  8. debian下为stm32f429i-discovery编译uboot
  9. 遇到“拒绝了对对象的 EXECUTE 权限”和“无法作为数据库主体执行,因为主体 "dbo" 不存在、无法模拟这种类型的主体,或您没有所需的权限”的问题
  10. JAVA强制类型转换(转载+自己的感想) - stemon