Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

es6 #12

Open
Seasons123 opened this issue May 31, 2017 · 1 comment
Open

es6 #12

Seasons123 opened this issue May 31, 2017 · 1 comment

Comments

@Seasons123
Copy link
Owner

Seasons123 commented May 31, 2017

Seasons123/ADReact#6

《es6标准入门》

第8章 函数的扩展

8.2 rest函数

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

  1. 下面的add函数是一个求和函数,利用rest参数可以像该函数传入任意数目的参数。
function add(...values){
  let sum =0 ;
  for (var val of values){
        sum+= val;  
  }
  return sum; 
}

add (2,5,3); //10

2.下面是一个rest参数代替arguments变量的例子。
(1)arguments变量的写法

const sortNumbers =( ) =>
Array.prototype.slice.call( arguments).sort( ) ;

(2)rest参数的例子

const sortNumbers=(...numbers) =>
numbers.sort( );

rest参数中的变量代表一个数组,所以数组特有的方法都可以用于这个变量。

3.下面是一个利用rest参数改写数组push方法的例子、

function push (array, ...items){
 items.forEach(function(item){
     array.push(item);
     console.log(item);
 });
}

var a=[];
push(a,1,2,3);

4.注意:
(1)rest参数之后不能再有其他的参数(即只能是最后一个参数),否则会报错。

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

(2)函数的length属性不包括rest参数
(function(a,...b){ }).length //1

@Seasons123
Copy link
Owner Author

Seasons123 commented May 31, 2017

8.3 扩展运算符

含义扩展运算符(spread)是三个点(...)。它好比rest参数的逆运算,将一个数组转为用逗号分隔的参数列表。
例:console.log( 1 , ...[2,3,4] , 5 ) //1 2 3 4 5
扩展运算符与正常的函数参数可以结合使用。

1.该运算符主要用于函数调用,该运算符将一个数组变成参数序列。
例1:

function push (array, ...items){
     array.push( ...items );
}

例2:

function add(x , y){
     return   x+y;
}
var numbers = [4,38];
add( ...numbers )    //42

2.替代数组的apply方法

例1:
由于扩展运算符可以展开数组,所以不再需要apply方法将数组转为函数的参数了。

//es5的写法
function f(x,y,z) { } 
var args = [0 , 1, 2] ;
f.apply(null, args);

//es6的写法,如1中的两个例子
function f(x,y,z) { } 
var args = [0 , 1, 2] ;
f(...args);

例2:
下面是扩展运算符取代apply方法的一个实际的例子,应用Math.max方法简化求数组最大元素的写法。

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

上面的代码表示,由于JavaScript不提供求数组最大元素的函数,所以只能套用Math.max函数将数组转为一个参数序列,然后求最大值。有了扩展运算符以后,就可以直接用Math.max了。

例3:
通过push函数,将一个数组添加到另一个数组的尾部。

//es5的写法
var arr1 = [0,1,2];
var arr2 = [3,4,5];
Array.prototype.push.apply( arr1 ,arr2);
//es6的写法
var arr1 = [0,1,2];
var arr2 = [3,4,5];
arr1.push( ...arr2);

上面的es5写法中,push方法的参数不能是数组,所以只好通过apply方法变通使用push方法。有了扩展运算符,就可以直接将数组传入push方法。

3.合并数组
例1:

//es5
[1 ,2].concat(more)
//es6
[1 ,2 , ...more]

例2:

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]

关于concat: http://www.w3school.com.cn/jsref/jsref_concat_array.asp

4.与结构赋值结合
扩展运算符可以与结构赋值结合起来用于生成数组

//例1
const [first , ...rest]=[ 1 ,2 ,3 ,4, 5];
first   //1
rest   //[2, 3, 4, 5]
//例2
const [first , ...rest]=[ ];
first   //undefined
rest   //[ ]
//注:将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错
const [ first ,  ...middle  ,  last ] =[ 1 , 2, 3, 4, 5]          //报错

5.扩展运算符可以将字符串转为真正的数组

//例1
[ ..."hello"]        //["h", "e" ,"l" , "l" ,"o"]
//例2:正确返回字符串长度
function length (str){
   return [ ...str].length;
}

6.类似数组的对象
任何类似数组的对象都可以用扩展运算符转为真正的数组。

//例:querySelectorAll方法返回的是一个nodeList对象,扩展运算符可以将其转为正真的数组。
var  nodeList = document.querySelectorAll( 'vid' );
var  array = [ ...nodeList];

7.Map和Set结构,Generator函数
扩展运算符内部调用的是数据结构的Iterator接口,因此只要具有Iterator接口的对象,都可以使用扩展运算符,比如Map结构。
例1:

let  map = ([
    [1,'one'],
    [2,'two'],
    [3,'three'],
]);
let  arr =[ ...map.key( ) ];        //[1,2,3]

例2:
Generator函数运行后返回一个遍历器对象,因此也可以使用扩展运算符。

var go = function *( ){
   yield 1;
   yield 2;
   yield 3;
};
[ ...go( ) ]        //[1,2,3]

上面的代码中,变量go是一个Generator函数,执行后返回的是一个遍历器对象,对这个遍历器对象执行扩展运算符,就会将内部遍历得到的值转为一个数组。

【注】如果对没有Iterator接口的对象使用扩展运算符,将会报错。

var obj = { a:1 , b:2 };
let  arr = [ ...obj ];        //TypeError:Cannot spread non-iterable object

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant