JavaScript函数

361 阅读5分钟

JavaScript函数

函数的定义和调用

function f1 (a,b) {
	if (a > b) {
    return a;
    } else {
    return b;
    }
  }

上述的函数 f1定义如下:

  • function 关键字定义函数
  • (a,b)是函数的名称
  • {}之间的代码是函数体,可以包含若干语句,也可以没有任何语句 注意:函数在遇到return时,就执行完毕,返回一个返回值。
    JavaScript函数也是一个对象,因此上面定义的函数f1()也是一个函数对象,所以也可以通过下面的这种方式定义函数:
let f2 = function (a,b) {
if (a > b) {
    return a;
    } else {
    return b;}}
    f2(4,5);//4

调用函数
按照顺序传入参数即可。此外,由于JavaScript允许传入任意个参数而不影响调用,因此传入的参数比定义的参数多也没问题。
f1(4,5,6,7,);//返回5;

变量的作用域

在JavaScript中声明的变量是有作用域的,如果一个变量在函数体内部申明,则这个变量的作用域为这个函数体,在函数外部不可以引用这个变量。

function f1()  {
    let a = 10;
    a += 1;
}
 a += 2; // Uncaught ReferenceError
  • 不同函数内部的同名变量互相独立,互不影响
  • JavaScript中的函数可以嵌套,内部函数可以访问外部函数的变量,反之则不行。
  • 如果内部函数定义了和外部函数同名的变量,则内部函数的变量将替代外部函数变量。

全局作用域

不在任何函数上定义的变量就具有全局作用域,实际上JavaScript默认有一个全局对象window,全局作用域的变量实际上被绑定到window的一个属性。

let a = 'cococo';
alert(a);
alert(window.a);

直接访问变量 a和访问 window.a是一样的。所以以变量的方式let f1 = function(){}定义的函数实际上也是一个全局变量,并绑定到window对象。

解构赋值

从ES6开始,JavaScript引入解构赋值,可以同时对一组变量赋值。

let [a1,a2,a3] = ['你好','我是','Nick'];

如果需要从一个对象中取出若干属性,也可以使用解构赋值,快速获取对象的指定属性。 使用解构赋值可以大大简化代码

let x =1,y = 2;
[x,y] = [y,x];
交换x和y的值

方法

在一个对象中绑定函数,这个函数称作方法。

let Nick = {
	name:'Nick',
    birth:1990,
    age: function() {
    let y = new Date().getFullYear();
    return y - this.birth;
    }
   };
Nick.age; // function Nick.age()
Nick.age(); //31

绑定到对象的函数叫做方法,但是它的内部使用了一个 this关键字。在一个方法内部, this是一个特殊的变量,它始终指向当前对象,也就是 Nick这个变量,所以this.birth可以拿到 Nickbirth属性。
但是如果把这个对象分开来写:

function getAge() {
    let y = new Date().getFullYear();
    return y - this.birth;
    }
let Nick = {
	name:'Nick',
    birth:1990,
   };
   
Nick.age();//31,正常结果
getAge();  //NaN

为什么单独调用getAge()返回了 NaN?
JavaScript的内部函数如果调用了 this,那么这个this指向谁?

  • 如果以对象的方法形式调用,比如Nick.age(),这个函数的 this指向被调用的对象,也就是 Nick
  • 如果单独调用函数,如 getAge(),此函数就会指向全局对象,也就是 window

高阶函数

JavaScript函数实际上都指向某个变量,既然变量可以指向函数,函数的参数就能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就是高阶函数。
一个简单的高阶函数:

function add(x,y,z) {
	return f(x) + f(y);
    }

Array.map()

map()方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。

funcion pow(x) {
	return x * x;
    }
let arr = [1,2,3,4,5];
let result = arr.map(pow);// [1,4,9,16,25]

Array.reduce()
reduce()方法对数组中的每个元素执行一个由你educer函数(升序执行),将其结果汇总为单个返回值。

  • reduce实现一个数组求和。
let arr = [1,3,5,7,9];
arr.reduce(function (x,y) {
return x + y;
}); //25
  • reduce 计算数组中每个元素出现的次数
let names = ['Alice','Nick','Bob','Alice','Bob','Bruce'];
let countedNames = names.reduce(function (allNames, name) {
	if (name in allNames) {
    allNames[name]++;
    } 
    	else {
        allNames[name] = 1;
        }
        return allNames;
        },{});
	//countedNames :{Alice: 2, Nick: 1, Bob: 2, Bruce: 1}

Array.filter()

Array.filter()创建一个新的数组,里面包含通过筛选条件的元素。与 map()类似的是 filter()也接受一个函数,但是不同的是 filter()把传入的函数一次作用于每个函数,根据返回值 true还是 false来决定保留还是丢弃。
保留奇数:

let arr = [2,3,23,5,6,68,32,97];
let arr1 = arr.filter(function(x) {
	return x % 2 != 0
    });

Array.sort()

sort()方法用原地算法对数组进行排序,并返回数组。默认排序顺序是将元素转换为字符串,再根据他们的UTF-16代码单元值序列。

  • 按照数字大小排序
let arr = [12,2,5,454,1,78];
arr.sort(function (x,y) {
	if(x<y) {
    return -1;
    }
    if(x>y) {
    return 1;;
    }
    return 0;
    });
console.log(arr); // [1,2,5,12,78,454]
//
let arr2 = [2,5,6,2,6,7,8,23,43];
arr.sort(function (a,b) {
    return a - b;
});
arr2;//[2, 3, 5, 6, 23, 32, 68, 97]

箭头函数

let fn = x => x * x;相当于:

function(x) {
	return x * x;
    }

如果不止有一个参数,需要括号括起来。
(x,y) => x + y;
如果需要返回一个对象,因为和函数体的语法有冲突,需要这样写:
`x => ({ fo: x});