ES6之函数的扩展知识点总结(六)

news/2024/7/10 22:41:30 标签: ES6, 函数扩展

本人学习ES6看的是阮一峰老师的书,写在博客里是因为,只看不动手总结,很多东西理解的不透彻,也容易忽略掉一些知识点,我也只是把我自己理解并且认为重要的总结在一起,如果想要对这一节有准确而深入的理解,请点击http://es6.ruanyifeng.com/#docs/function嗯、阮老师真的很厉害

函数参数的默认值

ES6允许为函数的参数设置默认值,即直接写在参数定义的后面。

function fn(x="donna"){
    console.log("hello:"+x);
}
fn();//hello:donna

注意:参数变量是默认声明的,所以不能用let或const再次声明(可以使用var声明)

function fn(x="donna"){
    let x = "leo";//SyntaxError: Identifier 'x' has already been declared
    console.log("hello:"+x);
}
fn();
function fn(x="donna"){
    var x = "leo";
    console.log("hello:"+x);
}
fn();//hello:leo

使用参数默认值时,函数不能有同名参数。

function fn(x="donna",x){//SyntaxError: Duplicate parameter name not allowed in this context
    console.log("hello:"+x);
}
fn();

但是,如果不设置默认值,是可以有同名参数的

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

另外,参数默认值不是传值的,而是每次都重新计算默认值表达式的值。也即是说,参数默认值时惰性求值的。
    let x = 100;
    let z = 0;
    function fn(y = x+1){
         z+= 3;
        console.log(y);
        console.log(z);
    }
    fn();//101   3
    fn();//101   6

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

function  fn({a,b="donna"}={}){
    console.log(a,b);
}
fn();//undefined "donna"
fn({a:1,b:"leo"});//1 "leo"

嗯、再来看个例子:

function fn1({a=0,b=0}={}){
    return console.log([a,b]);
}//设置了对象结构赋值的默认值,同时将函数参数的默认值设为空对象

function fn2({a,b}={a:0,b:0}){
    return console.log([a,b]);
}//没有对象结构赋值的默认值,但是将函数参数的默认值设为一个具有具体属性的对象
fn1();//[0,0]
fn2();//[0,0]
fn1({});//[0,0]
fn2({});//[undefined,undefined]
fn1({a:1});//[1,0]
fn2({a:1});//[1,undefined]
fn1({a:1,b:2});//[1,2]
fn2({a:1,b:2});//[1,2]
fn1({z:3});//[0,0]
fn2({z:3});//[undefined,undefined]

参数默认值的位置:通常情况下,定义了默认值的参数,应该是函数的尾参数。因为这样比较容易看出来,到底省略了哪些参数,如果非尾部的参数设置为默认值,实际上这个参数是没法省略的。

还有,如果传入undefined,将触发该参数等于默认值,null则没有这个效果

function fn(a="leo",b="donna"){
    console.log(a,b);
}
fn(undefined,null);//leo,null

函数的length属性(length属性的含义是:该函数预期传入的参数个数)

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

因为指定了默认值后,预期传入的参数个数就不包括这个参数了(同理,后面的rest参数也不会计入length属性)

rest参数

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

arguments对象不是数组,而是一个类似数组的对象。所以为了使用数组的方法,必须使用Array.prototype.slice.call()方法将其转为数组。rest参数就是一个数组,数组特有的方法它都可以使用。

注意:rest参数之后不能再有其他参数,否则会报错,并且函数的length属性不包括rest参数。

严格模式:从ES5开始,函数内部可以设定为严格模式。

function fn(a, b) {
  'use strict';
 
}

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

这样规定的原因是,函数内部的严格模式,同时适用于函数体和函数参数,但是,函数执行的时候,先执行函数参数,然后执行函数体。这样就有一个不合理的地方,只有从函数体之中,才能知道参数是否应该以严格模式执行,但是参数却因该先于函数体执行。

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

如果将一个匿名函数赋值给一个变量,ES5的name属性,会返回空字符串,而ES6的name属性会返回实际的函数名

如果将一个具名函数赋值给一个变量,ES5和S6的name属性都会返回这具名函数原本的名字

Function构造函数返回的函数实例,name属性的值为anonymous

bind返回的函数,name属性值会加上bound前缀

let fn1 = function fn(){

}
let fn2 = function(){}
let fn3 = function(){}
let fn4 = new Fun();
function Fun(){}
console.log(fn1.name);//fn
console.log(fn2.name);//fn2
console.log(fn3.bind().name);//bound fn3
console.log(fn4.name);//undefined
console.log((new Function).name);//anonymous

箭头函数:

ES6允许使用箭头函数(=>)

    //ES5函数写法
    var f = function fn(a){
        return a;
    }
  //ES6函数写法
   var f = a => a;

箭头函数的正确使用方式

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

2、如果箭头函数的代码块部分多于一条语句,就要使用大括号将他们括起来,并且使用return语句返回

3、如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错(因为大括号被解释为代码块)

4、如果箭头函数只有一行语句,且不需要返回值,可以使用下面的方法(前面加void),就不用写大括号了。

 document.onclick = ()=>void alert(0);
 document.onclick = (a,b)=>{
      alert(Number(null));//0
      alert(Number(b));//undefined
  };

使用箭头函数需要注意的点:

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

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

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

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

特别注意:this对象的指向是可变的,但是在箭头函数中,它是固定的。

    document.onclick =function(){
        setTimeout(()=>{
            alert(this);
        },100);
    }//[object HTMLDocument]
    var id = 1;
    var obj = {
        id:3
    }
    var obj2 = {
        id:4
    }
 function foo(){
     return ()=>{
         console.log(this.id);
     }
 }
    var fn = foo();
    foo()();//1(此时箭头函数定义时所在的对象是window)
    foo.call(obj)();//3(此时箭头函数定义时所在的对象是obj)
    fn.call(obj2);//1(此时箭头函数定义时所在的对象是window,注意箭头函数没有自己的this)

研究了好久才搞懂,嗯、注意,箭头函数的this指向是定义时所在的对象(切记是对象,本人刚开始没注意到,所以就总是感觉阮老师搞错了,最后才发现是自己没看仔细)

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

除了this,arguments、super、new.target三个变量在箭头函数中也是不存在的,指向外层函数的对应变量

箭头函数可以嵌套箭头函数

双冒号运算符:(::)“函数绑定运算符”

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

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

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

如果双冒号左边为空,右边是一个对象的方法,则等于将该方法绑定在该对象上面。

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

如果双冒号运算符的运算结果,还是一个对象,就可以采用链式写法

尾调用优化:

尾调用:是函数式编程的一个重要概念,指某个函数的最后一步是调用另一个函数

function f(x){
  return g(x);
}
一下三种情况都不属于尾调用
// 情况一
function f(x){
  let y = g(x);//调用g函数之后还有赋值操作
  return y;
}

// 情况二
function f(x){
  return g(x) + 1;//调用g函数之后还有操作
}

// 情况三
function f(x){
  g(x);
}//相当于在g(x)后面还有一个return undefined

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







http://www.niftyadmin.cn/n/952088.html

相关文章

vspython版本控制_git进行版本控制心得详谈

小编在学习可视化的时候,接触到git,所以这里写一下关于GitHub的有关知识,写这个的目的还是巩固自己的学习,一方面可以提高自己,另一方面回头看一下,有什么更深层次的东西还可以再记录。首先说一下版本控制软…

scipy学习

常量 from scipy import constants print(dir(constants))# [Avogadro, Boltzmann, Btu, Btu_IT, Btu_th, ConstantWarning, G, Julian_year, N_A, Planck, R, Rydberg, Stefan_Boltzmann, Wien, __all__, __builtins__, __cached__, __doc__, __file__, __loader__, __name__…

[翻译]简单谈谈事件与委托 (转)

Posted on 2007-04-08 12:56 Cruise 阅读(430) 评论(6) 编辑 收藏 所属分类: .net/CLR 、外文翻译 原文地址:http://www.codeproject.com/csharp/events.asp源代码下载:/Files/edgar-sun/events_src.zip演示文件下载:/Files/edgar-sun/even…

原生js+css实现带预览图片的幻灯片效果实例

先总结一下,里面的用到的关键知识点 CSS中用到的知识点有: 过渡效果:transition,下面是语法,用到时候一般要加上浏览器内核前缀。本实例中主要用到过渡的地方是opacity和right transition: property duration timing-f…

计算机使用经验分享_论文免费查重网站的使用经验分享

许多同学们的论文完成之后,都会去论文免费查重网站进行查重,以预估自己论文的查重比例如何,提前做好相应的修改,那么利用论文免费查重网站查重要注意些什么呢?下面一起来看看大家的经验分享吧!论文免费查重…

.Net 机制下委托(一) 事件委托

.net 机制下委托(一) 事件委托oldjacky原创 2005-6-4一、 认识委托一个简单的例子:张三看到餐桌上有一个桔子,由于自己怕动(主要是出于自己要玩游戏,走不开),立刻就对着他妈妈喊&…

ES6之Promise对象知识点总结(七)

还是要强调一下,我的ES6学习主要参考的是阮一峰大神的书,作笔记的目的,就是把对于我来说比较重要或者易错的点整理出来方便自己再次学习有所偏重,真的对这些不懂的请看原文:http://es6.ruanyifeng.com/#docs/promise阮…

原生js打造自定义播放器

用到的技术,主要是video的相关知识:实现的功能是去掉自带的控制条,按自己想要的形式设置视频的控制条:有播放与暂停(play()方法和pause()方法)、拖拽控制条控制视频的播放进度,并且控制条随着视…