es6 函数的扩展

函数参数: 显式参数(parameters)和隐式参数(arguments)

函数的显式参数在函数定义时列出

函数隐式参数在函数调用时传递给函数真正的值

参数规则:

        js函数定义显式参数时没有指定数据类型

        js函数对隐式参数没有进行类型检测

        js函数对隐式参数的个数没有进行检测

函数的默认值es6允许函数参数设置默认值,即可以直接写在参数定义的后面

function fn(a,b='true'){
    console.log(a,b)
}

fn('false')  // false true
fn('false','no') //false no
fn('false','') //false

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

function foo({x, y = 5}) {
  console.log(x, y);
}

foo({}) // undefined, 5
foo({x: 1}) // 1, 5
foo({x: 1, y: 2}) // 1, 2
foo() // 报错

函数的length属性

如果设置默认值的参数在最后,设置了默认值之后,函数的length属性就失效了一样,不再计算这个值的长度

如果设置默认值的参数在最前面,则length不会往下计算长度

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

作用域

name属性   指函数的名称

** 箭 头 函 数   =>

箭头函数会默认帮我们绑定外层this的值,所以箭头函数中的this的值和外层的this是一样的

箭头函数不能提升的,需要在使用前定义

使用const比使用var更安全,因为函数表达式始终是一个常量

如果函数部分只是一个语句,则可以省略return关键字和大括号

     1:  函数体内的this对象,是指定义时的对象,并非使用的时候所在的对象

     2:  不可以当作构造函数,也就是说,不可以使用new命令,不然会出错

     3:  不可以使用arguments对象,该对象在函数体内不存在arguments,如果要使用,可以使用Reast

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

  

     箭头函数中,this的指向是固定的

function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

var id = 21;

foo.call({ id: 42 });
// id: 42

上面的这个this指向不是window,而是指向函数定义所在对象的id

箭头函数可以让setTimeout里面的this,绑定定义时所在的作用域,而不是指向运行时所在的作用域。

箭头函数没有自己的this ,所以不能使用call,apply.bind去改变this的指向

箭头函数可以嵌套使用

let insert = (value) => ({into: (array) => ({after: (afterValue) => {
  array.splice(array.indexOf(afterValue) + 1, 0, value);
  return array;
}})});

insert(2).into([1, 3]).after(1); //[1, 2, 3]

绑定this 

函数绑定运算符 是并排的两个双冒号(::)  ,双冒号左边是一个对象,右边是一个函数,该运算符会自动将左边的对象作为上下文的this

绑定到右边的函数中

foo::bar;
// 等同于
bar.bind(foo);

foo::bar(...arguments);
// 等同于
bar.apply(foo, arguments);

const hasOwnProperty = Object.prototype.hasOwnProperty;
function hasOwn(obj, key) {
  return obj::hasOwnProperty(key);
}

如果双冒号左边为空,右边是一个对象的时候,会将这个方法绑定到对象中去

var method = obj::obj.foo;
// 等同于
var method = ::obj.foo;

let log = ::console.log;
// 等同于
var log = console.log.bind(console);

由于双冒号运算符返回的还是原对象,因此可以采用链式写法。

// 例一
import { map, takeWhile, forEach } from "iterlib";

getPlayers()
::map(x => x.character())
::takeWhile(x => x.strength > 100)
::forEach(x => console.log(x));

// 例二
let { find, html } = jake;

document.querySelectorAll("div.myClass")
::find("p")
::html("hahaha");

尾调用优化     函数的最后一步调用另一个函数

function f(x){
  return g(x);
}

尾调用不一定出现在函数的尾部,只要是最后一步操作就可以

尾调用优化,就是只保留内层函数的调用帧.如果所有的函数都是尾调用,那么完全可以做到每次

执行时,调用帧只有一项,这会大大节省内存

但是只有在不再用到外层函数的内部变量,内层函数的调用帧才会取代外层函数的调用帧,否则就无法使用

尾递归    函数调用自身,称为递归,如果尾调用自身,就是尾递归

function Fibonacci2 (n , ac1 = 1 , ac2 = 1) {
  if( n <= 1 ) {return ac2};

  return Fibonacci2 (n - 1, ac2, ac1 + ac2);
}

Fibonacci2(100) // 573147844013817200000
Fibonacci2(1000) // 7.0330367711422765e+208
Fibonacci2(10000) // Infinity

只要使用尾递归,就不会发生栈溢出,节省内存

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值