> 文章列表 > [ES6]函数

[ES6]函数

[ES6]函数

[ES6]函数

  • 常规函数
  • 函数参数的扩展
    • 默认参数
    • 不定参数
  • 箭头函数
    • 箭头函数的优势
  • 箭头函数与常规函数的区别
    • 动态 this
  • 举例说明

常规函数

function test() {if (undefined === window.env || null === window.env) {window.env = "xxx";}
}

函数参数的扩展

默认参数

给参数设置默认值

function fn(name, age = 17) {console.log(name + "," + age);
}
fn("Amy", 18); // Amy,18// 不报错
function fn(name, name) {console.log(name);
}
//不报错
function fn(name, name, age) {console.log(name);console.log(age);
}
// 以下均报错,任何参数设置默认值均报错
//SyntaxError: Duplicate parameter name not allowed in this context
function fn(name, name, age = 17) {console.log(name + "," + age);
}
function fn(name = 1, name, age) {console.log(name + "," + age);
}
function fn(name, name = 1, age) {console.log(name + "," + age);
}

当函数参数列表有同名参数时,只要其中任意参数设置了默认值均会报错

function f(x, y = x) {console.log(x, y);
}
f(1); // 1 1,这里的y并不是undefinedfunction f(x = y) {//这里的y也不是作为undefined传递给xconsole.log(x);
}
f(); // ReferenceError: y is not defined

函数参数设置默认值可能导致暂时性死区,在函数参数默认值表达式中,还未初始化赋值的参数值无法作为其他参数的默认值

不定参数

不定参数表示不确定参数的个数,形如,…变量名,由…加上一个具名参数标识符组成。具名参数只能放在参数组的最后,并且有且只有一个不定参数

function f(...values) {console.log(values.length);
}
f(1, 2); //2

箭头函数

箭头函数 – =>,箭头函数提供了一种更加简洁的函数书写方式:参数 => 函数体

  • 箭头函数没有参数或者有多个参数,参数位置要用 () 括起来
  • 箭头函数函数体有多行语句,用 {} 包裹起来,表示代码块,当只有一行语句,并且需要返回结果时,可以省略 {} , 结果会自动返回
let test = () => {if (undefined === window.env || null === window.env) {window.env = "xxx";}
};

在函数内容使用 this,常规函数指向 onlineEnv,箭头函数指向 onlineEnv 所在的 scop

// 报错
var f = (id,name) => {id: id, name: name};
f(6,2);  // SyntaxError: Unexpected token :// 不报错
var f = (id,name) => ({id: id, name: name});
f(6,2);  // {id: 6, name: 2}

箭头函数要返回对象的时候,为了区分于代码块,要用 () 将对象包裹起来

箭头函数的优势

let onlineEnv = (a) => {return a * a;
};

返回值只有一行,可以去除{},与 return 关键字

let onlineEnv = (a) => a * a;

如果参数只有一个,可以去除参数的()

let onlineEnv = (a) => a * a;

箭头函数与常规函数的区别

在常规函数中 this 指向的是函数所在对象;

在箭头函数中 this 指向的是外部环境

var func = () => {// 箭头函数里面没有 this 对象,// 此时的 this 是外层的 this 对象,即 Windowconsole.log(this);
};
func(55); // Windowvar func = () => {console.log(arguments);
};
func(55); // ReferenceError: arguments is not defined

注意:没有 this、super、arguments 和 new.target 绑定

箭头函数体中的 this 对象,是定义函数时的对象,而不是使用函数时的对象

ES6 之前,JavaScript 的 this 对象一直很令人头大,回调函数,经常看到 var self = this 这样的代码,为了将外部 this 传递到回调函数中,那么有了箭头函数,就不需要这样做了,直接使用 this 就行

function fn() {setTimeout(() => {// 定义时,this 绑定的是 fn 中的 this 对象console.log(this.a);}, 0);
}
var a = 20;
// fn 的 this 对象为 {a: 18}
fn.call({ a: 18 }); // 18

不可以作为构造函数,也就是不能使用 new 命令,否则会报错

var Person = {age: 18,sayHello: () => {console.log(this.age);}
};
var age = 20;
Person.sayHello(); // 20
// 此时 this 指向的是全局对象var Person1 = {age: 18,sayHello: function () {console.log(this.age);}
};
var age = 20;
Person1.sayHello(); // 18
// 此时的 this 指向 Person1 对象

动态 this

var button = document.getElementById("userClick");
button.addEventListener("click", () => {this.classList.toggle("on");
});

button 的监听函数是箭头函数,所以监听函数里面的 this 指向的是定义的时候外层的 this 对象,即 Window,导致无法操作到被点击的按钮对象

举例说明

this.id = "console to show this";const testThis = {func1: function () {console.log("func1", this);},func2: () => {console.log("func2", this);},func3: {func31: function () {console.log("func31", this);},func32: () => {console.log("func32", this);}}
};
const func4 = function () {console.log("func4", this);
};testThis.func1();
testThis.func2();
testThis.func3.func31();
testThis.func3.func32();func4();

输出:

func1 {func1: [Function: func1],func2: [Function: func2],func3: { func31: [Function: func31], func32: [Function: func32] }
}
func2 { id: 'console to show this' }
func31 { func31: [Function: func31], func32: [Function: func32] }
func32 { id: 'console to show this' }
func4 <ref *1> Object [global] {global: [Circular *1],queueMicrotask: [Function: queueMicrotask],clearImmediate: [Function: clearImmediate],setImmediate: [Function: setImmediate] {[Symbol(nodejs.util.promisify.custom)]: [Getter]},structuredClone: [Function: structuredClone],clearInterval: [Function: clearInterval],clearTimeout: [Function: clearTimeout],setInterval: [Function: setInterval],setTimeout: [Function: setTimeout] {[Symbol(nodejs.util.promisify.custom)]: [Getter]},atob: [Function: atob],btoa: [Function: btoa],performance: Performance {nodeTiming: PerformanceNodeTiming {name: 'node',entryType: 'node',startTime: 0,duration: 43.73209999501705,nodeStart: 2.7523999959230423,v8Start: 6.356099992990494,bootstrapComplete: 27.509199991822243,environment: 14.54169999063015,loopStart: -1,loopExit: -1,idleTime: 0},timeOrigin: 1680579070496.426},fetch: [AsyncFunction: fetch]
}