参数默认值:
// function fn(name, // age=100, // arr=[], // obj={}, // call=function(){}){ // //参数1是必须传递 // //其余参数有默认值,可选传递 // console.log(name); // console.log(age); // console.log(arr); // console.log(obj); // console.log(call('callback')); // } // fn(name="苏玮一",age=200,arrr=[1,2,3],obj={key:1},call=function(info){ // return info; // }); //函数参数的默认值,可以是另一个函数的返回值 // function pi(){ // return 3.1415926; // } // function fn(r,p=pi()){ //把pi的值传给p // console.log(r*r*p); // } // fn(r=10); //如果只想传递第二往后的参数,参数一保持默认值 可用undefined占位 // function fn(name="苏玮一",age){//null ,空 都不行 // console.log(name); // console.log(age); // } // fn(undefined,age=21); //支持参数二使用参数一作为默认值,反之不可以 // function fn(a,b=a){ //(b=a,a) 是错误的 不可以 // console.log(a); // console.log(b); // } // fn(a=2); //解构变量有不定元素,函数的参数也可以有不定参数 // function fn(name,...val){ //不定参数之后不可再有参数 // console.log(name); // console.log(val); // } // fn(name="苏玮一",val=21,'女');
name属性:
//ES6提供了一个name属性用于获取函数名,以方便开发者 // function fn(){ // } // let f2=function(){}; // let obj={ // fn3:function(){} // }; // console.log(fn.name); // console.log(f2.name); // console.log(obj.fn3.name); // console.log((new Function()).name); //匿名函数 anonymous
箭头函数:
//ES6新增了一个使用(=>)箭头有符号的语法特性 // let fn=name=>name; // console.log(fn(name="苏玮一")); // //翻译为函数代码 // let fn=function(name){ // return name; // } //箭头函数也可以传递两个或两个以上的参数 // let fn=(x,y)=>x+y; // console.log(fn(10,20)); // //翻译为函数代码 // let fn=function(x,y){ // return x+y; // } //如果定义的函数,并不需要传递参数,可以用()括号方式直接返回 // let fn=()=>"苏玮一"; // console.log(fn()); // 翻译为函数代码 // let fn=function(){ // return "苏玮一"; // } //如果函数体需要更复杂的操作,可以将箭头符号右边使用传统函数体 // let fn=(x,y)=>{ // return x+y; // }; // console.log(fn(10,10)); //如果箭头符号右边是对象,返回的是对象,需要用圆括号包含 // let fn=name=>({name:name,age:21}); // console.log(fn(name="苏玮一").name); // // 翻译为函数代码 // let fn=function(name){ // return{ // name:name, // age:21 // } // } //如果箭头函数左边是对象作为参数,右边是对象的属性运算 // let fn=({name,age})=>name+","+age; // console.log(fn({name:"苏玮一",age:"21"})); // 翻译为函数代码 // let fn=function({name,age}){ // return{ // name:name, // age:21 // } // } //自我立即执行函数,也可以使用箭头符号来创建 // ((name)=>{ // console.log(name); // })("苏玮一") // // 翻译为函数代码 // (function(name){ // console.log(name); // })("苏玮一")
绑定this:
//this在全局的时候指向的是我window,在某个对象内部指向当前对象 //在web环境下,它指向了window,而node环境下指向setTimeout //将this在setTimeout外部进行赋值保存 let obj={ name:"苏玮一", age:21, fn:function(){ // // console.log(this.name); // let that=this; // setTimeout(function(){ // console.log(that);//obj对象包含类似setTimeout函数内部,这时this指向就出现问题 // console.log(that.name+","+that.age); // },500); //箭头函数彻底解决了this在内部指向的问题,直接指向我们需要的 //因为箭头函数中的this是最外层定义的函数绑定,不受内部影响 setTimeout(()=>{ console.log(this); console.log(this.name+","+this.age); },500); } } obj.fn();
箭头扩展:
//箭头函数支持一些内置函数的使用 // let arr=[3,1,2,5,4].sort(function(a,b){ // return a-b;//[ 1, 2, 3, 4, 5 ] // }) //翻译为函数代码 // let arr=[3,1,2,5,4].sort((a,b)=>a-b); // console.log(arr); //箭头函数不支持arguments绑定,直接用...other模式(rest运算符) // let fn=(x,y)=>{ // return arguments[0]+arguments[1];//不支持 // } //不确定参数 用...other // let fn=(...val)=>{ // return val[0]+val[1]; // } // console.log(fn(10,20)); // //箭头函数和普通函数一样,都可以被typeof和instanceof进行验证 // console.log(typeof fn); // console.log(fn instanceof Function);
尾调用优化:
什么又是尾调用优化?为何要优化?因为:每次尾调用都会创建栈帧;
如果尾调次数过多,而内存中的调用栈越来越大,可能就会出现程序问题;
尤其是在递归函数的问题上,尾调用优化适合在这种场景中使用;
首先要说明,尾调用优化必须是在 ES6 的严格模式下,'use strict';
严格模式,可以设置为全局作用域,也可以在函数体内有效;
严格模式对变量、对象和函数做了一些代码规范等等,具体规范可以搜索;
而对于尾调用,必须严格按照三个规则,才能执行严格模式下的优化,如下:
(1) .尾调用必须 return 返回; // go(x); 错误
(2) .尾调用 return 返回不得含其它操作 // return go(x) + 1; 错误
(3) .尾调用 return 返回的不是函数,而是函数赋值的变量,不在尾部;
//let result = go(x);
//return result;
//尾调用:在一个函数的最后可执行的一步调用了其他函数 // function go(x){ // return x+20; // } // let fn=function(x){ // return go(x); // } // console.log(fn(10)); //回调函数 // 开启严格模式 'use stirct' 'use stirct' function fn(x){ // console.log(x); if(x<=1){ return 1; } return fn(x-1); } fn(10);
新增方法:
//对于一些超过两个字符(四字节)的异体字,ES6 新增了 codePointAt()方法; //两个字符的异体字,这里用?代替,文档显示不出来,上面土,下面口 // let text = '?'; // console.log(text.length); //2 // console.log(text.charAt(0)); //? // console.log(text.charCodeAt(0)); //55362 // console.log(text.charCodeAt(1)); //57271 // console.log(text.codePointAt(0)); //134071,十进制码点 // //一个字符的简体字 // let text = '吉'; // console.log(text.length); //1 // console.log(text.charAt(0)); //吉 // console.log(text.charCodeAt(0)); //21513 // console.log(text.charCodeAt(1)); //NaN // console.log(text.codePointAt(0)); //21513 //ES6 提供 normalize()方法用于有音标的符号组合形式进行统一; // console.log('\u01D1'); // console.log('\u004F'); // console.log('\u030C'); // console.log('\u004F\u030C'.normalize() == '\u01D1'.normalize()); //ES6 提供了三种判断字符串的方法:includes()、startsWith()和 endsWith(); let text = '你好,大美女!'; console.log(text.includes("你"));//true,是否找到'你' console.log(text.startsWith("你"));//必须从头开始查找 console.log(text.endsWith("!"));//必须从尾部开始查找 console.log(text.includes('你', 8)); //false,超过位置,第二参数寻找的位置 //repeat()重复字符串,padStart()补全字符串头部,padEnd()补全字符串尾部; console.log('x'.repeat(5)); console.log('xyz'.repeat(3)); console.log('Mr.Lee'.repeat(0)); //空 console.log('x'.padStart(5, 'Mr')); //MrMrx console.log('x'.padEnd(5, 'Mr')); //xMrMr //---------------模板字符串------------------ //在 ES6 之前,字符串内夹杂变量,我们总是通过分离和+号连接解决; // let name="苏玮一",age=21; // text="我是"+name+",今年"+age+"岁"; // console.log(text); //可以直接使用(`)反引号配合${var}模版语法格式,直接实现变量解析功能 //支持多行操作 // text=`我是${name},今年${age}岁`; // console.log(text); // 如果我们想在字符串中插入表达式,也可以使用${a + b}模版语法; // text = `一加一等于:${1+1}`; //${${}}这种模版嵌套的方式,也是支持的; // text = `结果:${flag ? 'true' : 'false'}`; // text = `结果:${flag ? `true${1+1}` : 'false'}`; //可以使用 String.raw 来得到原生字符串; // text = String.raw `我\n 是`;
正则的扩展改进:
// u 修饰符,对占两个字符特殊字进行正则识别; // let text = '𠮷'; // let result=/吉{2}/.test("吉吉"); // let result=/𠮷{2}/.test("𠮷𠮷"); // console.log(result); // y 修饰符,它的作用是当匹配过一次后继续往下匹配 // let text = 'xxx_xx_x_', patt = /x+_/y; // console.log(patt.exec(text)); //xxx_ // console.log(patt.exec(text)); //xx_ // console.log(patt.exec(text)); //x_ //对于 y 修饰符,ES6 提供了 stikcy 属性,用来检测是否存在 y 修饰符 // console.log(patt.sticky); //ES6 提供了 flags 属性,用于返回正则使用的修饰符名称 // console.log(patt.flags); // . 表示匹配所有,除了终止符,比如回车\n 换行\n 等等,使用 s 修饰符匹配; // let text="x\nyz",patt = /x.+yz/s; // console.log(patt.test(text));; //ES6 支持修饰符替换,之前会报错 let regex = new RegExp(/xyz/iu, 'g'); console.log(regex.flags); //g
数值的扩展改进:
// 二进制、八进制和十六进制分别用 0b、0o、0x 作为前缀; console.log(Number('0b11')); console.log(Number('0o11')); console.log(Number('0x11')); //Number.isFinitel()、Number.isNaN()判断无穷大和 NaN; //非数值为 false,数值为 true console.log(Number.isFinite(100)); //NaN 为 true,其余为 false console.log(Number.isNaN(100)); //Number.parseInt()、Number.parseFloat()转换整型和浮点型; console.log(Number.parseInt('55.55a')); console.log(Number.parseFloat('55.555b')); //Number.isInteger(),来判断参数是否是一个整型; console.log(Number.isInteger(10)); //一个常量,值特别小,用于判断是否得到正确结果 // console.log((0.1 + 0.22 - 0.3).toFixed(20)); console.log(Number.EPSILON); console.log(Number.EPSILON.toFixed(30)); // 直观的看 console.log((0.1 + 0.2 - 0.3) < Number.EPSILON); //ES6+新增了一个指数运算符 **,并且可以进行赋值运算; console.log(2 ** 4); //16,4 个 2 相乘 let num = 2; num **= 5; console.log(num); //32,5 个 2 相乘 //----------------Math扩展----------- //ES6 对 Math 对象新增了一些方法.trunc()、.sign()、cbrt()、clz32() .imul() .fround() .hypot()、expm1()、.log1p()、log10()、log2(); console.log(Math.trunc(5.55)); //去掉小数部分
浙公网安备 33010602011771号