美文网首页
4.函数的扩展

4.函数的扩展

作者: KeithFu | 来源:发表于2016-11-24 19:01 被阅读0次

函数参数的默认值

function log(x, y = 'World') {
 console.log(x, y);
}
log('Hello') // Hello World

function Point(x = 0, y = 0) { 
this.x = x; 
this.y = y;
}
var p = new Point();
p // { x: 0, y: 0 }

解构赋值默认值的使用:

function fetch(url, { body = '', method = 'GET', headers = {} }) { 
console.log(method);
}
fetch('http://example.com', {})// "GET"
fetch('http://example.com')// 报错

函数的length属性:
指定了默认值以后,函数的length
属性,将返回没有指定默认值的参数个数。也就是说,指定了默认值后,length
属性将失真。

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

利用参数默认值,可以指定某一个参数不得省略,如果省略就抛出一个错误

function throwIfMissing() { 
  throw new Error('Missing parameter');
}

function foo(mustBeProvided = throwIfMissing()) {
   return mustBeProvided;
}
foo()

rest参数

ES6引入rest参数(形式为“...变量名”),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中。与java中的可变形参功能一样。

// arguments变量的写法
function sortNumbers() { 
return Array.prototype.slice.call(arguments).sort();
}
// rest参数的写法
const sortNumbers = (...numbers) => numbers.sort();

扩展运算符

扩展运算符(spread)是三个点(...)。它好比rest参数的逆运算,将一个数组转为用逗号分隔的参数序列。

console.log(...[1, 2, 3])
// 1 2 3
console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
[...document.querySelectorAll('div')]
// [<div>, <div>, <div>]

// ES5的写法
Math.max.apply(null, [14, 3, 77])
// ES6的写法
Math.max(...[14, 3, 77])
// 等同于
Math.max(14, 3, 77);

扩展运算符的应用

  • 合并数组
// ES5
[1, 2].concat(more)
// ES6
[1, 2, ...more]
var arr1 = ['a', 'b'];
var arr2 = ['c'];
var arr3 = ['d', 'e'];
// ES5的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6的合并数组
[...arr1, ...arr2, ...arr3
]// [ 'a', 'b', 'c', 'd', 'e' ]
  • 与解构赋值结合
    扩展运算符可以与解构赋值结合起来,用于生成数组。
const [first, ...rest] = [1, 2, 3, 4, 5];
first 
// 1
rest  
// [2, 3, 4, 5]
const [first, ...rest] = [];
first
 // undefined
rest 
 // []
const [first, ...rest] = ["foo"];
first 
 // "foo"
rest  
// []
  • 字符串
[...'hello'];
[...'hello'].reverse().join("")
  • 实现了Iterator接口的对象
    任何Iterator接口的对象,都可以用扩展运算符转为真正的数组。
var nodeList = document.querySelectorAll('div');var array = [...nodeList];
  • Map和Set结构,Generator函数
    扩展运算符内部调用的是数据结构的Iterator接口,因此只要具有Iterator接口的对象,都可以使用扩展运算符,比如Map结构。
 let map = new Map([
    [1, 'one'], 
    [2, 'two'], 
    [3, 'three'],
]);
let arr = [...map.keys()]; // [1, 2, 3]

var go = function*(){
 yield 1;
 yield 2; 
yield 3;
};
[...go()]
 // [1, 2, 3]
  • 严格模式
    从ES5开始,函数内部可以设定为严格模式。
function doSomething(a, b) { 
'use strict'; 
 // code
}

只要函数参数使用了默认值、解构赋值、或者扩展运算符,那么函数内部就不能显式设定为严格模式,否则会报错。但可以如下解决(包含在一个立即执行的函数里):

const doSomething = (function () {
   'use strict';
    return function(value = 42) {
       return value;
 };
}());
  • name属性
    函数的name属性,返回该函数的函数名。

  • 箭头函数

var f = v => v; 

上面的箭头函数等同于:

var f = function(v) { return v;};```

如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。
由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号。

var getTempItem = id => ({ id: id, name: "Temp" });

箭头函数可以与变量解构结合使用。

const full = ({ first, last }) => first + ' ' + last;
// 等同于
function full(person) {
return person.first + ' ' + person.last;
}

箭头函数的一个用处是简化回调函数。

// 正常函数写法
[1,2,3].map(function (x) { return x * x;});
// 箭头函数写法
[1,2,3].map(x => x * x);

rest用法

const numbers = (...nums) => nums;
numbers(1, 2, 3, 4, 5)// [1,2,3,4,5]
const headAndTail = (head, ...tail) => [head, tail];
headAndTail(1, 2, 3, 4, 5)// [1,[2,3,4,5]]

+ 使用注意点
     箭头函数有几个使用注意点。
  - 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
 - 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
 - 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替。
 - 不可以使用yield命令,因此箭头函数不能用作Generator函数。

上面四点中,第一点尤其值得注意。this对象的指向是可变的,但是在箭头函数中,它是固定的。

function Timer() {
this.s1 = 0;
this.s2 = 0;
// 箭头函数
setInterval(() => this.s1++, 1000);
// 普通函数
setInterval(function () {
this.s2++;
}, 1000);}
var timer = new Timer();
setTimeout(() => console.log('s1: ', timer.s1), 3100);
setTimeout(() => console.log('s2: ', timer.s2), 3100);
// s1: 3// s2: 0

箭头函数可以让this指向固定化,这种特性很有利于封装回调函数

所以,箭头函数转成ES5的代码如下。

// ES6function foo() {
setTimeout(() => {
console.log('id:', this.id); }, 100);
}
// ES5
function foo() {
var _this = this;
setTimeout(function () {
console.log('id:', _this.id);
}, 100);
}

下面是一个部署管道机制(pipeline)的例子,即前一个函数的输出是后一个函数的输入。

const pipeline = (...funcs) => val => funcs.reduce((a, b) => b(a), val);
const plus1 = a => a + 1;
const mult2 = a => a * 2;
const addThenMult = pipeline(plus1, mult2);
addThenMult(5)// 12

相关文章

  • 4.函数的扩展

    函数参数的默认值 解构赋值默认值的使用: 函数的length属性:指定了默认值以后,函数的length属性,将返回...

  • ES6

    1.模版字符串:`String` 2.对象解构赋值 3.函数扩展:rest参数 4.箭头函数 箭头函数的特点 4....

  • 第四章:ES6总结

    1.变量: let,const2.函数: 箭头函数,函数参数(参数扩展) 函数默认参数3.数组方法4.字符串5.p...

  • ES6 学习笔记--------目录

    1.let 和 const 命令 2.变量的解构赋值 3.字符串的扩展 4.正则的扩展 5.数值的扩展 6.函数的...

  • Kotlin 笔记 扩展

    扩展(extension)是指向已有的类中添加函数 扩展函数 定义扩展函数时,在函数前面加上要扩展类的名字,以下代...

  • 重拾Kotlin(12)-扩展函数和扩展属性

    一、扩展函数和扩展属性 1.1、扩展函数 扩展函数用于为一个类增加一种新的行为,这是为缺少有用函数的类进行扩展的途...

  • JavaScript的构造函数扩展、继承以及封装

    构造函数的扩展 扩展Man构造函数 构造函数的继承 Dog 继承 Pig JavaScript 内置对象的扩展 例...

  • web-jianshu es6/es7新语法

    1.let和const 2.数组的解构 3.对象的解构 4.函数参数的解构 5.数组的扩展 6.对象的扩展 7.函...

  • 2021-11-30(Kotlin学习笔记)Kotlin 基础(

    kotlin java 隔离 kotlin 扩展函数 java 中调用扩展函数 高级函数

  • 浅谈Kotlin语法篇之扩展函数(五)

    1、为什么要使用Kotlin中的扩展函数? 2、怎么去使用扩展函数和扩展属性? 3、什么是扩展函数和属性? 4、扩...

网友评论

      本文标题:4.函数的扩展

      本文链接:https://www.haomeiwen.com/subject/rwibpttx.html