ES6(三) 函数 4

2020-05-12  本文已影响0人  蒋小花_4b6c

1.块级函数 

(在if里面声明函数,会不会变量提升?有let就不会提升,function Name(){}就会被提升;

会提升到哪里?es6会提升到全局,其他情况会提升到if顶部)

2.箭头函数 * 

    调用函数表达式 IIFE

    没有 this 绑定

    箭头函数与数组

    没有 arguments 绑定

    识别箭头函数

块级函数

ES5(严格模式)不允许 在代码块中声明函数(即块级函数),像这样:

"use strict";

if (true) {

    function doSomething() { }  // 在 ES5 会抛出语法错误, ES6 则不会

}

ES6 则不会, 

ES6 会将 doSomething() 函数视为块级声明, 并允许它在定义所在的代码块内部被访问。

"use strict";

if (true) {

    console.log(typeof doSomething); // "function" // 变量提升

    function doSomething() {}

    doSomething();

}

console.log(typeof doSomething); // "undefined"

决定何时使用块级函数

块级函数与 let 函数表达式相似,在执行流跳出定义所在的代码块之后,函数定义就会被移 除。

关键区别在于:块级函数会被提升到所在代码块的顶部;而使用let 的函数表达式则不 会,

var getName = function() {

    console.log(typeof name); // 错误

    let name = 'Sam';

    console.log(typeof name); // string

    console.log(typeof sayName); // 错误

    let sayName = function() {

        console.log('sayName');

    }

    console.log(typeof sayName); // function

    console.log(typeof backName); // function

    function backName() {

        return 'backName';

    }

    console.log(typeof backName); // function

}

getName();

非严格模式的块级函数

ES6非严格模式

// ES6 behavior

if (true) {

    console.log(typeof doSomething); // function

    function doSomething() {}     

    doSomething();

}

console.log(typeof doSomething); // function

块级函数的作用域会被提 升到所在函数或全局环境的顶部,而不是代码块的顶部。

箭头函数

使用一个“箭头”( =>  )来定义.

与传统的 JS 函数的区别:

    没有 this  super  arguments  ,也没有new.target  绑定: this  、 super 、 arguments  、以及函数内部的new.target 的值由所在的、最靠近的非箭头函数来决定

    不能被使用 new 调用: 箭头函数没有 [[Construct]] 方法,因此不能被用为构造函 数,使用new 调用箭头函数会抛出错误。

    没有原型: 既然不能对箭头函数使用 new ,那么它也不需要原型,也就是没有prototype 属性。

    不能更改 this : this 的值在函数内部不能被修改,在函数的整个生命周期内其值会 保持不变。

    没有 arguments 对象: 既然箭头函数没有 arguments 绑定,你必须依赖于具名参数或 剩余参数来访问函数的参数。

    不允许重复的具名参数:箭头函数不允许拥有重复的具名参数,无论是否在严格模式 下;而相对来说,传统函数只有在严格模式下才禁止这种重复。

    但是:箭头函数也拥有 name 属性,并且遵循与其他函数相同的规则.

如果没有参数:

var reflect = _ => 'this is returnTxt';

var reflect = function() {

    return 'this is returnTxt';

}

如果是一个参数:

var reflect = value => value;

var reflect = function(value) {

    return value;

};

如果是多个参数:

var reflect = (num1, num2) => num1 + num2;

var reflect = function(num1, num2) {

    return num1 + num2;   

}

如果函数体内容较多,也可使用{ return…}

var reflect = (a, b) => {

    return a + b;

}

var reflect = function(a, b) {

    return a + b;

}

如果没有函数体的空函数:

var reflect = () => {}

var reflect = function() {}

如果 返回一个对象字面量:

var getTempItem = (id) => ({ id: id, name: 'Temp'});

var getTempItem = function(id) {

    return {

        id,

        name: 'Temp'

    }

}

注意:箭头函数返回对象是用()圆括号括起来的.

标示了括号内是一个字面量而不是函数体.

## 创建立即调用函数表达式(IIFE)

 IIFE 允许你定义一个匿名函数并在未保存引用的情况下立刻调用它。

当你想创建一个作用域并隔离在程序其他部分外,这种模式就很有用了。

// 匿名函数立即执行IIFE

let person = function(name) {

    return {

        getName: function() {

            return name;

        }

    };

}("Nicholas");

console.log(person.getName()); // Nicholas

// 箭头函数立即执行IIFE

let person = ((name) => {

    return {

        getName: function() {

            return name;

        }

    };

})("Nicholas");

console.log(person.getName()); // Nicholas

注意箭头函数的括号,只包括了函数的定义.

// 传统一般函数

(function() {})()

(function() {} ())

// 箭头函数

(() => {})()

没有 this 绑定

常见bug函数内的 this 绑定

由于一个函数内部的 this 值可以 被改变,这取决于调用该函数时的上下文,

因此完全可能错误地影响了一个对象,尽管你本 意是要修改另一个对象.

var PageHandler = {

    id: "123456",

    init: function() {

        document.addEventListener("click", function(event) {

            console.log(this);

            // this.doSomething(event.type);    // 错误

            // 此处的this指的是document.而不是PgeHandler

        }, false);

    },

    doSomething: function(type) {

        console.log("Handling " + type  + " for " + this.id);

    }

};

PageHandler.init();

// 解决方案

//  使用bing方法,将函数的this绑定到PageHandler

var PageHandler0 = {

    id: "123456",

    init: function() {

        document.addEventListener("click", (function(event) {

            console.log(this);

            // this.doSomething(event.type);    // 没有错误

        }).bind(this), false);

    },

    doSomething: function(type) {

        console.log("Handling " + type  + " for " + this.id);

    }

};

PageHandler0.init();

// 调用 bind(this) ,你实际上创建 了一个新函数,

// 它的 this 被绑定到当前 this (也就是 PageHandler )上。

// 因此,建议使用箭头函数

var PageHandler1 = { 

    id: "123456",

    init: function() {

        document.addEventListener("click",

            event => this.doSomething(event.type), false);

    },

    doSomething: function(type) {

        console.log("Handling " + type  + " for " + this.id);

    }

};

由于箭头函数的 this  值由包含它的函数决定,因此不能使用call()  、 apply() 或 bind()  方法来改变其 this 值。

箭头函数与数组

var result = values.sort(function(a, b) {

    return a - b;

});

var result = values.sort((a, b) => a - b);

就是简化代码

没有 arguments 绑定

尽管箭头函数没有自己的 arguments 对象,但仍然能访问包含它的函数的 arguments 对 象。无论此后箭头函数在何处执行,该对象都是可用的。

function createArrowFunctionReturningFirstArg() {

    return () => arguments[0];

}

var arrowFunction = createArrowFunctionReturningFirstArg(5);

console.log(arrowFunction()); // 5

识别箭头函数

var comparator = (a, b) => a - b;

console.log(typeof comparator);

console.log(comparator instanceof Function);

可以对箭头函数使用 call() 、 apply() 与 bind() 方法,

虽然函数的 this  绑定并不会受影响。

var sum = (num1, num2) => num1 + num2;

console.log(sum.call(null, 1, 2));  // 3

console.log(sum.apply(null, [1, 2]));   // 3

var boundSum = sum.bind(null, 1, 2);

console.log(boundSum()); // 3

上一篇 下一篇

猜你喜欢

热点阅读