一、定义与调用
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;};
二、变量作用域
若内部变量名与外部变量名重名,优先使用内部变量。
不在任何函数内定义的变量具有全局作用域,如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;}
三、解析赋值
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‘];
解析赋值也可用于快速从对象中获取变量。
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);
四、对象方法
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());//truelet lambda = Rectangle.isSquare;alert(lambda());//falsealert(lambda.apply(Rectangle, []));//true(参数为空)
五、高阶函数
以其他函数作为参数的函数称之为高阶函数。
function f1(a, b, f) { ???return f(a) + f(b);}let f2 = Math.abs;let result = f1(-1, -3, f2);alert(result);
通过调用数组对象的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]
六、闭包
函数可以作为返回值,但是如果返回的函数引用了局部变量,该局部变量不应是任何后续会发生变化的,因为返回的函数会延后调用。
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]
由于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]
七、箭头函数
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
JS笔记:函数
原文地址:https://www.cnblogs.com/arseneyao/p/8724607.html