JS笔记:函数

Posted arseneyao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS笔记:函数相关的知识,希望对你有一定的参考价值。

一、定义与调用

arguments为当前函数调用者传入的所有参数。由于JS的函数可以接受任意数量的参数,我们可以利用arguments来获取所有参数。

ES6引入了rest参数,便于我们可以直接获取未定义但是被传入的参数。

技术分享图片
function f1(arg) {
    var result = 0;
    for (var i = 1; i < arguments.length; i++)
        result += arguments[i];
    return result;
}

var f2 = function (arg, ...rest) {
    var result = 0;
    for (var i of rest)
        result += i;
    return result;
};
View Code

 

二、变量作用域

若内部变量名与外部变量名重名,优先使用内部变量。

不在任何函数内定义的变量具有全局作用域,如window对象。

调用拥有全局作用域的变量中的函数不需要显示指明对象,如window.alert函数。

使用var无法定义具有块级作用域(例如循环)的变量,为此JS引入了let与const。

技术分享图片
function f() {
    let result = 0;
    for (let i = 0; i < arguments.length; i++)
        result += arguments[i];
    return result;
}
View Code

 

三、解析赋值

ES6之后JS引入了解析赋值,可以同时对一组变量进行赋值。

技术分享图片
//传统写法
const arr = [‘Hello‘, ‘JS‘, ‘ES6‘];
let str1 = arr[0];
let str2 = arr[1];
let str3 = arr[2];

//解析赋值
let [strA, strB, strC] = [‘Hello‘, ‘JS‘, ‘ES6‘];
View Code

解析赋值也可用于快速从对象中获取变量。

技术分享图片
let Player = {
    name: ‘Stephen Curry‘,
    information: {
        team: ‘Golden State Warriors‘,
        number: 30,
        position: ‘Point Guard‘
    }
};

let {name, information: {team, number}} = Player;
alert(name + team + number);
View Code

 

四、对象方法

this指针只有在显式知名调用方法的对象时才指向对象本身,否则指向全局对象window。

在strict模式下函数中的strict指向undefined。该特性只是让错误暴露,并未解决this的指向问题。

在独立调用的函数中,若希望this指针指向对象而非window或undefined,则需要使用apply。

技术分享图片
‘use strict‘;

let Rectangle = {
    length: 10,
    height: 10,
    isSquare: function () {
        if (this === window || this === undefined)
            return false;
        else return this.length === this.height;
    }
};

alert(Rectangle.isSquare());//true
let lambda = Rectangle.isSquare;
alert(lambda());//false
alert(lambda.apply(Rectangle, []));//true(参数为空)
View Code

 

五、高阶函数

以其他函数作为参数的函数称之为高阶函数。

技术分享图片
function f1(a, b, f) {
    return f(a) + f(b);
}

let f2 = Math.abs;
let result = f1(-1, -3, f2);
alert(result);
View Code

通过调用数组对象的map方法可以产生指定映射的新数组。

调用reduce方法获取对数组所有元素进行指定二元运算的结果。

调用filter方法将数组的特定元素过滤并返回剩余的元素。

调用sort方法将数组排序,需要注意的是sort方法会默认将所有的元素以字符串的形式进行排序,若希望以数字的形式进行排序,必须自定义比较规则。

技术分享图片
let arr = [-1, -2, -3, -4, -5];

//map示例
let result = arr.map(Math.abs);//[1,2,3,4,5]

//reduce示例
let f1 = function (a, b) {
    return a + b;
};
let result1 = arr.reduce(f1);//-15

//filter示例
let f2 = function (x) {
    return x % 2 !== 0;
};
let result2 = arr.filter(f2);//[-1,-3,-5]

//sort示例
let f3 = function (a, b) {
    return a - b;
};
let result3 = arr.sort(f3);//[-5,-4,-3,-2,-1]
View Code

 

六、闭包

函数可以作为返回值,但是如果返回的函数引用了局部变量,该局部变量不应是任何后续会发生变化的,因为返回的函数会延后调用。

技术分享图片
function f() {
    var arr = [];
    for (var i = 0; i < 3; i++) {
        arr.push(function () {
            return i;
        });
    }
    return arr;
}

var arr = f();
var result = [];
for (var i = 0; i < arr.length; i++)
    result[i] = arr[i]();
alert(result);//[3,3,3]
View Code

由于JS没有类,所以需要借助闭包来封装私有变量。简单来说闭包就是携带状态的函数,并且其状态完全可以对外界隐藏。

技术分享图片
function counter(initial) {
    let t = initial || 0;
    return {
        add: function () {
            t++;
            return t;
        }
    }
}

let arr = [];
let c1 = counter();
for (let i = 0; i < 3; i++)
    arr[i] = c1.add();
alert(arr);//[0,1,2]

let c2 = counter(10);
for (let i = 0; i < 3; i++)
    arr[i] = c2.add();
alert(arr);//[10,11,12]
View Code

 

七、箭头函数

ES6加入了箭头函数,相当于匿名函数。

箭头函数与匿名函数的区别是,箭头函数内部的this是词法作用域,由上下文确定,修复了this的指向问题。

技术分享图片
‘use strict‘;

let obj1 = {
    information: ‘Hello‘,
    getInformation: function () {
        return function () {
            return this.information;//this指向window或undefined
        };
    }
};

let getInfo = obj1.getInformation();
alert(getInfo());//无法输出

let obj2 = {
    description: ‘World‘,
    getDescription: function () {
        return () => this.description;//this指向obj
    }
};

let getDesc = obj2.getDescription();
alert(getDesc());//输出World
View Code

 

以上是关于JS笔记:函数的主要内容,如果未能解决你的问题,请参考以下文章

几个关于js数组方法reduce的经典片段

web代码片段

JS常用代码片段-127个常用罗列-值得收藏

ES7-Es8 js代码片段

js-权威指南学习笔记14

学习笔记:python3,代码片段(2017)