理解javascript 函数

162 阅读3分钟

声明一个普通的函数,并且调用它。

sum();
function sum(x){
  console.log(x); // undefined
}

当我们没有传入参数的时候,参数的默认值为undefined,当然我们传入更多的参数也是多余的,js的函数参数是按照循序传入的。 函数声明提升,也就是说你可以先调用函数再去声明它。

创建一个匿名函数(函数表达式)你必须先声明再使用。

let fn = function(x,y,z){
	console.log(arguments); // { '0': 1, '1': 2 }
	return x + y;
    console.log(x+y); // 不会执行
}
fn();
console.log(fn(1,2)); // 3

函数会在return之后停止并立即退出。 arguments对象与数组类似,它可以获取函数的传入的实际参数,通过方括号访问arguments[0]得到1。

所有JavaScript函数都是按值传递的。

let num= 10;
function add(n){
	n += 1;
	console.log(n);
}
add(num); 
console.log(num); // 10

function setName(obj){
	obj.name = 'tom';
	obj = {};
	obj.name = 'john';
}

const p = {};
setName(p);
console.log(p.name); // tom

JavaScript对象是按引用访问的,但是函数参数只能按值传递。 以上代码实际会在setName函数的内部创建一个新的对象,然后修改它的属性值,这个对象会在函数执行完毕后立即被销毁。

递归函数

function factorial(num){
	if(num == 1){
		return 1;
	}else{
		return num * factorial(num - 1);
	}
}

console.log(factorial(5)); //120

函数重复调用自身计算5的阶乘,递归的关键是控制结束的条件。

闭包,通常指内部函数访问外部函数作用域中的变量和参数,优点是可以减少全局的变量命名污染, 缺点是导致外部函数的活动对象长期驻留内存,可能导致内存泄漏。

function father(){
	let a = 1;
	return function(){
		console.log(a + 1);
	}
}

let son = father();
son();
son = null; // 释放内存

关于this对象。

let person = {
	name: 'tom',
	say: function(){
		console.log(this.name);
	}
}
person.say(); // tom

let sayHi = person.say;
sayHi(); // undefined

如果有学习过JavaScript关于this指向的问题,这样的代码应该很熟悉了。 改变函数this指向的方式有很多,bind、call、apply等,此处不再细说,读者请自行查阅相关资料。

sayHi.bind(person)(); // tom

箭头函数,除了简写(=>)代码,省略单行return语句之后的好处,就是解决this指向问题。

const func = n => n*2;
console.log(func(2));
const func2 = ()=>{
	console.log(this); // Window
}
func2();

箭头函数体内的this对象是定义时所在的对象,而不是使用时所在的对象,它的固定的。

函数参数默认值

function test({x,y=2}){
	console.log(x,y); // undefined 2
}
test({});

这里函数参数默认值与结构赋值默认值结合使用,我们必须传入一个对象,没有的属性y会采用默认值2,参数默认值的位置应该是在结尾。

rest参数用于获取函数的多余参数,现在我们不需要arguments对象了,而且它是一个真正的数组。

function rest(args1,...rest) {
	console.log(rest); // [2,3]
}
rest(1,2,3);

柯里化(Currying),柯里化是一种函数的转换,它是指将一个函数从可调用的 f(a, b, c) 转换为可调用的 f(a)(b)(c)。

function name(fn) {
	return function (age) {
		return function(height) {
  			return fn(age,height)
		}
	}
}

function info(age,height) {
	return {
		age,
		height
	}
}

let newFn = name(info);
let x = newFn(20)(180) // { age: 20, height: 180 }
console.log(x);