美文网首页
阮一峰的ES6---函数的扩展

阮一峰的ES6---函数的扩展

作者: 一名职业程序员 | 来源:发表于2018-09-06 16:58 被阅读0次

函数的扩展

一,函数参数的默认值

在ES5中,设置参数的默认值:

function (x,y){ x = x || "hello"; y = y || " world"; console.log(x+y); } //但是如果y赋值为false时,那么y还是为默认值 因此要先判断x和y的数据类型 function(x,y){ if(typeof x === 'undefined'){ x="hello"; } if(typeof y === 'undefined'){ y=" world"; } console.log(x+y); }

ES6允许在参数的默认值直接写在参数后面

function Person (name="MGT360124", age=18){    this.name = name;    this.age = age;}let p = new Person();p//{name:"MGT360124",age:18}

参数变量是默认声明的,不能用let 或者const再次声明。使用默认参数时,函数不能有同名参数;

function fn(x = 5){ let x=1;//errorconst x= 2;//error}function fn(x,x,y){//允许}function fn(x,y,y=10){//出错}

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

参数默认值可以与解构赋值的默认值,结合起来使用

function fn(x,y=5){ console.log(x,y);}fn({})//undefined 5fn({x:1})//1 5fn({x:1,y:2})//1 2fn();//TypeError :cannot read property "x" of undefined

三,参数默认值的位置

function person(name,age=18,sex){return [x,y,z];}person()//[undefined ,18, undefined]person("MGT")//["MGT",18,undefined ]person("MGT", , 'M')//errorperson("MGT",undefined,"M")//["MGT",18,"M"]

四,函数的length属性

length属性的返回值,等于函数的参数个数减去指定了默认值的参数个数

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

如果设置了默认值的参数不是尾参数,那么length属性也不再计入后面的参数了。

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

五,作用域

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

var x= 1;function fn(x,y =x){console.log(y)}fn(2);//2

参数y的默认值就等于变量x,调用函数时,参数形成一个单独的作用域,在这个作用域里面,默认值变量y指向第一个参数x,而不是全局变量x,所以输出的是2;

let x =1;function fn(y =x){ let x =2;console.log(y);}fn();//1

上面的代码中,函数调用时,参数y = x形成一个单独的作用域,这个作用域里面,变量x本身没有定义,所以指向外层的全局变量x,函数调用时,函数体内部的局部变量影响不到默认值的变量x;如果全局变量x不存在,那么就会报错

function fn(y=x){let x =3;console.log(y);}fn();//ReferenceError :x is not defined

六,rest参数(...变量名)

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

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

add是一个求和函数,利用rest参数可以求任意数目的参数

严格模式

ES2016 做了一点修改,规定只要函数参数使用了默认值、解构赋值、或者扩展运算符,那么函数内部就不能显式设定为严格模式,否则会报错。

七,name属性

函数name属性,返回该函数的函数名

function person(){}person.name //'person'

箭头函数(=>)

var f = v => v;//等同于var f = function(v) {return v;}

如果箭头函数不需要参数或者需要多个参数,就使用一个圆括号代表参数部分。

var f = () => 5;f()//5//等同于var f = function (){ return 5};var sum = (num1,num2)  =>num1+num2;//等同于var sum = function(num1,num2){        return num1+num1;}sum(1,2)//3

由于花括号{}被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上一个括号,否则会报错

let getTempItem = id =>( {id:id,name:'MGT'} )getTempItem(360124)//{id:360124,name:"MGT"}//等同于let getTempItem = function(id){    return { id:id, name:"MGT" };}getTempItem(360124)

如果箭头函数只有一行语句,且不需要返回值:

let fun = () => void doesNotReturn();

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

let full = ({first,escond}) => first +" "+ second ;//等同于function full(person){      return person.first +" "+person.last;}

箭头函数简化回调函数

[1,2,3].map(function(x){return x*x})//[1,4,9]//简化[1,2,3].map(x=>x*x);

箭头函数的注意点

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

(2)不可以当作构造函数,不能使用new命令

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

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

this对象的指向是可变的,但是在箭头函数中,他是固定的

funnction foo(){        setTimeout( () => {            console.log("id :", this.id);                },1000);}var id =21;foo.call( { id:42} );// id :42

setTimeoout的参数是一个箭头函数,这个箭头函数的定义生效是在foo函数生成时,而它真正执行要等到1000毫秒以后,如果他是普通函数,执行时this应该指向全局对象window,这时输出的是21,但是箭头函数导致this总是指向函数定义生效时所在的对象{id :42},所以输出42;

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

Timer函数内部设置了两个定时器,分别为箭头函数和普通函数,前者的this绑定定义时所在的作用域(为TImer函数),后者的this指向运行时所在的作用域(window),所以3100毫秒之后,timer.s1更新了3次,而timer.s2一次都没更新;

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

var handler ={ id :"123456", init :function () {        document.addEventListener("click",            event => this.doSomething(event.type), false);            },      doSomething:function (type) {        console.log('handling '+type + " for " +this.id);      }};

this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this,正是因为他没有this,所以也就不能用作构造函数。

由于箭头函数没有自己的this,所以当然也就不能用call().apply(),bind()这些方法去改变this的指向;

相关文章

  • 阮一峰的ES6---函数的扩展

    函数的扩展 一,函数参数的默认值 在ES5中,设置参数的默认值: function(x,y){x=x||"hell...

  • es6---函数扩展

    函数扩展 函数参数的默认值 基本用法 当y的值为false或者‘’时,其实还是应该输出fasle和’',正确的判断...

  • 05. 正则的扩展

    正则的扩展 原书作者:阮一峰 原书地址:ECMASript 6入门 RegExp构造函数修饰符后行断言(提案) ...

  • 阮一峰:函数

    JavaScript 语言将函数看作一种值,与其它值(数值、字符串、布尔值等等)地位相同。凡是可以使用值的地方,就...

  • js 普通对象继承

    //非构造函数继承 参考自:阮一峰

  • JS函数(阮一峰)

    函数是一段可反复调用的代码块。函数能接受输入参数,不同参数返回不同的值。 1. 概述 1.1 声明 functio...

  • Javascript 面向对象编程(一):封装

    封装:作者:阮一峰 继承: 非构造函数的继承 前端网站资源

  • JavaScript(ES6) - Array

    数组的扩展--转自:阮一峰《ECMAScript 6 入门》 Array.from( Array.from方法用于...

  • 【JavaScript】技术参考资料

    JS基础、高级、进阶 MDN·JavaScript 函数式编程 阮一峰老师的入门简介: 函数式编程初探、函数式编程...

  • ES6数值扩展

    阮一峰大神的ES6数值篇已经写的很好很全,下边贴出链接,然后斗胆写一点自己学习的总结。阮一峰ES6数值扩展我准备从...

网友评论

      本文标题:阮一峰的ES6---函数的扩展

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