函数形参的默认参数:
总结:
ES5中默认参数的设置:
function play(url , time , callback){
url = url||'';
time = time || '2000';
}
缺点 :当 time为0 时 也会被判断为false
安全版本:
function play(url , time , callback){
callback = (typeof callback !== "undefined")? callback:function e(){
return 'aa';
};
time = (typeof time !== "undefined")?time:'2000';
console.info(url,time,callback());
}
ES6中的默认参数设置:
function play(url, time = '2000', callback = function() {
return "aa";
}) {
console.info(url, time, callback());
}
默认参数对arguments对象的影响:
es5在非严格模式下,会改变arguments的值
es5非严格:
function mixArguments(one, two) {
console.info(arguments);//["a", "b"]
one = 1;
two = 2;
console.info(arguments);//[1, 2]
console.info(one === arguments[0]);// true
console.info(two === arguments[1]);// true
}
mixArguments('a','b');
es5严格模式:
function mixArguments(one, two) {
"use strict"//启用严格模式
console.info(arguments);//["a", "b"]
one = 1;
two = 2;
console.info(arguments);//["a", "b"]
console.info(one === arguments[0]);// false
console.info(two === arguments[1]);// false
}
mixArguments('a','b');
在es6下:
默认的参数不在函数里 而且启动严格模式
function mixArguments(one, two=2) {
console.info(arguments.length);//1 !!
console.info(arguments);//{ '0': 'a' }
console.info(one === arguments[0]);//true
console.info(two === arguments[1]);//false !!!
}
默认参数表达式:
可以将其它参数设置为已传形参:
function test(first , second=first){
console.info(first,second);//1,1
}
console.info(test(1)
也可以传递一个函数:
前一个形参不能使用后一个形参做默认
let val=2;
function add(first){
return val+first;
}
function test(first , second=add(first)){
console.info(first,second);//1,3
}
console.info(test(1));
es5无命名参数:
//类似java不定参数
function pick(object) {
let result = Object.create(null);
for (var i = 1; i < arguments.length; i++) {
result[arguments[i]] = object[arguments[i]];
}
return result;
}
let stu={
name:'xiaoyang',
age:'21'
};
console.info(pick(stu,'name','age'));
es6不定参数:
function pick(object,..keys){
let result=Object.create(null);
for (var i = 0; i < keys.length; i++) {
result[keys[i]]=object[keys[i]];
}
return result;
}
不定参数限制:
必须在末尾
不能用于字面量的setter方法
arguments包含所有不定参数值
增强Funtion构造函数:
es6可以这样写:
let f=new Function('a','b=a','return a+b');
console.info(f(1));//2
展开运算符:
ES5处理最大、最小值数组:
var values = [11,222,332,12];
console.info(Math.max.apply(null,values));
ES6处理最大、最小值数组:
var values = [11,222,332,12];
console.info(Math.max(...values));
console.info(Math.max(...values,22));//也可以与一般参数混用 执行顺序是 先比较values里的 两两比较 然后比较后面的
ES6中 函数的名称:
function doIt(){}
var doit=function(){}
console.info(doIt.name);//doIt
console.info(doit.name);//dolt
特殊情况:
以函数后的名字为准
var aa = function Hanshu(){
}
var person = {
get firstName(){
return 'aas';
},
sayName:function (){
}
}
console.info(aa.name);//Hanshu
console.info(person.firstName.name);//undefined
console.info(person.sayName.name);//sayName
通过bind创建的函数:
var thing= function() {};
console.info(thing.bind().name);//bound thing 绑定创建 带有bound
console.info(new Function().name);//anonymous
不要用函数name属性来获取变量
明确函数的多用途性:
早期的es有多重功能 如
function Person(name){
this.name=name;
}
var person =new Person('xiaomin');
var notAPerson = Person('xiaozhao');
console.info(person); //
Person {name: "xiaomin"}
console.info(notAPerson);//
undefined
es5判断函数被调用方法:
function Person(name){
if(this instanceof Person){
this.name=name;//new的时候调用
}else{
throw new Error('不能直接使用');
}
}
var person =new Person('xiaomin');
var notAPerson = Person('xiaozhao');//Error: 不能直接使用
// 这种方法也有不可靠的时候 用call的就不保错
var callPerson = Person.call(person,'xiaomin');
console.info(callPerson);
ES6 判断是否new 方法:
function Person(name){
if(typeof new.target !== 'undefined'){
this.name=name;
}else{
throw new Error('不能直接使用');
}
}
var person =new Person('xiaomin');
//var notAPerson = Person('xiaozhao');//Error: 不能直接使用
var callPerson = Person.call(person,'xiaomin');//不能直接使用
也可以判断是否是被某个特定构造函数调用:
这里的构造函数一定必须是原函数的
function Person(name){
if(typeof new.target !== 'undefined'){
this.name=name;
}else{
throw new Error('不能直接使用');
}
}
function AnotherPerson(name){
Person.call(this,name);
}
var person =new Person('xiaomin');
var ap =new AnotherPerson('xiaoz');//不能直接使用
块级函数:
"use strict";
function test(){
if(true){
function e(){
console.info('success'); //es5 抛出语法错误 es6不会 因为 es5 会把function 的变量提升到最外层方法
}
}
}
然而并没啥子用,let e=function (){}就行
然后 如果不用严格模式 会直接提升到全局
好了 下面才是很重要的:
箭头函数:
1 、
箭头函数没有 this\super\arguments\new.targer 这些绑定 默认的这些属性 是 箭头函数上级非箭头函数的
2、
不能通过new 调用 //箭头函数没有construct构造方法 所以不能new
3、
没有原型
4、
不可改变this绑定
5、
不支持arguments对象
6、
不支持重复命名参数
箭头函数也有箭头属性
箭头函数语法:
单参数:
let ref=value=>value;
[let|const] name=[arg|(args,args)|()]=>[returns|{ ... } ]
多参数:
let ref=(value,arr)=>value+arr;
创建立即执行函数表达式:IIFE
ES5版本:
let test1=(function (name){
return {
getName:function (){
return name;
}
}
})('xiaomin');
console.info(test1.getName());//xiaomin
ES6箭头函数版本:
let test2=((name)=>{
return {
getName:function (){
return name;
}
};
})('xiaomin');
console.info(test2.getName());//xiaomin
ES5this处理:
一般情况下 喜欢使用var self来调用 :
书上有种新方法:
let PageHandler =
{
id:22,
init: function(){
setTimeout((function(){
this.id=1;
console.info(this);
}).bind(this) ,"3000");
}
}
console.log(PageHandler.init());
箭头函数就不会出现这种问题
箭头函数不受call\apply\bind影响:
可调用 但是不影响
var sum=(a,b)=>a+b;
console.info(sum.call(null,1,2));//3
console.info(sum.apply(null,[1,2]));//3
console.info(sum.bind(null,1,2));//3
尾调用优化:
条件:
不是闭包
最后一条
调用结果作为返回值返回
返回时不做任何处理
适用范围:
递归