ES6 -- 函数

参数默认值

function sum(a, b, c) {
    // b = b || 1;
    // c = c || 1;

    b = b === undefined && 1;
    c = c === undefined && 1;

    return a + b + c;
}

console.log(sum(10, 11, 12)); // 33

使用

在书写形参时,直接给形参赋值,赋的值即为默认值。

这样一来,当调用函数时,如果没有给对应的参数赋值(给它的值是undefined),则会自动使用默认值。

function sum(a, b = 1, c = 1) {

    return a + b + c;
}

console.log(sum(10)); // 12
<div id="container"></div>

<script>
    const parent = document.getElementById("container");

    function craeteElement(name = "div", container = parent, content = "") {
        const ele = document.createElement(name);

        if(content) {
            ele.innerHTML = content;
        }
        container.appendChild(ele);
    }

    // craeteElement("div", parent, "123");

    craeteElement(undefined, undefined, "123");
</script>

对 arguments 的影响

function test(a, b) {
    console.log("a:", a, "b:", b); // a: 1 b: 2
    console.log(arguments); // [1, 2]

    a = 3;
    console.log("a:", a, "b:", b); // a: 3 b: 2
    console.log(arguments); // [3, 2]
}
test(1, 2);

严格模式下:

"use strict"
function test(a, b) {
    console.log("a:", a, "b:", b); // a: 1 b: 2
    console.log(arguments); // [1, 2]

    a = 3;
    console.log("a:", a, "b:", b); // a: 3 b: 2
    console.log(arguments); // [1, 2]
}
test(1, 2);

只要给函数加上参数默认值,该函数会自动变成严格模式下的规则:argument 和 形参脱离。

function test(a = 1, b = 3) {
    console.log("a:", a, "b:", b); // a: 2 b: 3
    console.log(arguments); // [2]

    a = 3;
    console.log("a:", a, "b:", b); // a: 3 b: 3
    console.log(arguments); // [2]
}
test(2);

留意暂时性死区

形参和ES6中的let和const声明一样,具有作用域,并且根据参数的声明顺序,存在暂时性死区。

function test(a = b, b) {
    console.log(a, b); // Cannot access 'b' before initialization
}
test(undefined, 1);

剩余参数

function sum(arg) {
    let sum = 0;
    for(let i = 0; i < arg.length; i ++) {
        sum += arg[i];
    }
    return sum;
}

console.log(sum([1])); // 1
console.log(sum([1, 2, 3, 4])); // 10

arguments的缺陷:

  1. 如果和形参配合使用,容易导致混乱。
  2. 从语义上,使用arguments获取参数,由于形参缺失,无法从语义上理解函数的真实意图。
function sum() {
    let sum = 0;
    for(let i = 0; i < arguments.length; i ++) {
        sum += arguments[i];
    }
    return sum;
}

console.log(sum(1)); // 1
console.log(sum(1, 2, 3, 4)); // 10

ES6的剩余参数专门用于收集末尾的所有参数,将其放置到形参数组中。

语法:

function (...形参名) {

}
function sum(...args) {
    // args 收集了所有的参数,形成一个数组
    // console.log(args);
    
    let sum = 0;
    for(let i = 0; i < args.length; i ++) {
        sum += args[i];
    }
    return sum;
}

console.log(sum(1)); // 1
console.log(sum(1, 2, 3, 4)); // 10

细节:
1. 一个函数,只能出现一个剩余参数。
2. 一个函数,如果有剩余参数,剩余参数必须是最后一个参数。

展开运算符

使用方式: ...要展开的东西

对 数组展开 ES6

// 对所有数组求和
function sum(...args) {
    let sum = 0;
    for(let i = 0; i < args.length; i ++) {
        sum += args[i];
    }
    return sum;
}

// 获取一个指定长度的随机数组成的数组
function getRandomNumbers(length) {
    const arr = [];
    for(let i = 0; i < length; i ++) {
        arr.push(Math.random());
    }
    return arr;
}

const numbers = getRandomNumbers(10);
console.log(numbers);

// 将数组的每一项展开,依次作为参数传递,而不是把整个数组作为一个参数传递
console.log(sum(...numbers)); // 相当于传递了10个参数 

深度克隆:

const arr1 = [1, 2, 3];
const arr2 = [...arr1];

console.log(arr2, arr2 === arr1); //  [1, 2, 3]    false

对 对象展开 ES7

const obj1 = {
    name: "刘",
    age: 20
}

const obj2 = {
    ...obj1
}

console.log(obj2, obj2 === obj1); //  {name: "刘", age: 20}   false

明确函数的双重用途

使用构造函数,或使用普通函数。

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.fullName = `${firstName} ${lastName}`;
}

const p1 = new Person("p1", "p");
console.log(p1); // {firstName: "p1", lastName: "p", fullName: "p1 p"}

const p2 = Person("p2", "p");
console.log(p2); // undefined
function Person(firstName, lastName) {
    // 判断是否是使用new的方式来调用函数

    // 过去的判断方式
    if(!(this instanceof Person)) {
        throw new Error("该函数没有使用new来调用");
    }

    this.firstName = firstName;
    this.lastName = lastName;
    this.fullName = `${firstName} ${lastName}`;
}

const p1 = new Person("p1", "p");
console.log(p1); // {firstName: "p1", lastName: "p", fullName: "p1 p"}

// 可避开判断
const p3 = Person.call(p1, "p3", "p");
console.log(p3); // undefined

const p2 = Person("p2", "p");
console.log(p2); // Uncaught Error: 该函数没有使用new来调用

ES6提供了一个特殊的API,可以使用该API在函数内部,判断该函数是否使用了new来调用。

new.target
// 该表达式,得到的是:如果没有使用new来调用函数,则返回undefined;如果使用new调用函数,则得到的是new关键字后面的函数本身
function Person(firstName, lastName) {
    // 判断是否是使用new的方式来调用函数

    // ES6 判断方法
    // console.log(new.target);
    if(new.target === undefined) {
        throw new Error("该函数没有使用new来调用");
    }

    this.firstName = firstName;
    this.lastName = lastName;
    this.fullName = `${firstName} ${lastName}`;
}

const p1 = new Person("p1", "p");
console.log(p1); // Person {firstName: "p1", lastName: "p", fullName: "p1 p"}

const p3 = Person.call(p1, "p3", "p");
console.log(p3); // Uncaught Error: 该函数没有使用new来调用

const p2 = Person("p2", "p");
console.log(p2);

箭头函数

回顾:this指向

  • 1.通过对象调用函数,this指向对象
  • 2.直接调用函数,this指向全局对象
  • 3.如果通过new调用函数,this指向新创建的对象
  • 4.如果通过apply、call、bind调用函数,this指向指定的数据
  • 5.如果是DOM事件函数,this指向事件源
const obj = {
    count: 0,
    start: function() {
        console.log(this); //  this --> obj
        setInterval(function() {
            console.log(this); // this --> window
            this.count ++;
            console.log(this.count); // NaN
        },1000)
    }
}

obj.start();
const obj = {
    count: 0,
    start: function() {
        // console.log(this); //  this --> obj
        var self = this;
        setInterval(function() {
            console.log(self); // this --> obj
            self.count ++;
            console.log(self.count);
        },1000)
    }
}

obj.start();

使用语法

箭头函数是一个函数表达式,理论上,任何使用函数表达式的场景都可以使用箭头函数。

完整写法:

(参数1, 参数2) => {
    // 函数体
}
const obj = {
    count: 0,
    start: function() {
        console.log(this); //  this --> obj
        
        setInterval(() => {
            console.log(this); // this --> obj
            this.count ++;
            console.log(this.count);
        },1000)
    }
}

obj.start();

如果参数只有一个,可以省略小括号:

参数 => {
    // 函数体
}

如果箭头函数只有一条返回语句,可以省略大括号,和return关键字:

参数 => 返回值

注意细节

  • 箭头函数的函数体中的this,取决于箭头函数定义的位置的this指向,而与如何调用无关。

1. 箭头函数中,不存在 this、arguments、new.target ,如果使用了,则使用的是函数外层的对应的 this、arguments、new.target 。

2. 箭头函数没有原型。

3. 箭头函数不能作为构造函数使用。

应用场景

1. 临时性使用的函数,并不会刻意调用它。比如:事件处理函数、异步处理函数、其他临时性的函数。

2. 为了绑定外层this的函数。

3. 在不影响其他代码的情况下,保持代码的简洁。最常见的是数组方法中的回调函数。

const num = [3, 5, 5, 3, 2];

const result = num.filter(num => num % 2 === 0).map(num => num * 2);

console.log(result); // [4]
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容