函数种类
名称 | 写法 | 解释 |
---|---|---|
普通函数 | function foo(){} | |
箭头函数 | const foo = ()=>{} | |
generator | function* foo(){} | ES6的一种异步编程解决方案 |
constructor函数 | class Foo{ constructor(){…} } | 类的构造函数 |
async函数 | async function foo(){} | Generator 函数的语法糖 |
立即执行函数
通过立即执行函数(IIFE)可以实现块级作用域
(function(){ var a = 1;
//这里是块级作用域,里面定义的变量外部无法访问(除非return出去)
})();
console.log(a); // Uncaught ReferenceError: a is not defined
ES6以后已经有了块级作用域的概念了,因此IIFE已经逐渐退出历史舞台了。
闭包
闭包是指有权访问另一个函数作用域中的变量的函数。常见方式,就是在一个函数内部创建另一个函数
var closure = function(){
var count = 0;
return function(){ return count ++; }}
const fn = closure();
console.log(fn()); // 0
console.log(fn()); // 1
console.log(fn()); // 2
fn = closure() 相当于 fn = function(){ return count ++; } , fn一直保持着对这个匿名函数的引用,而这个匿名函数又引用着count变量。因此count变量一直存在于执行上下文中,不会消失。
闭包通常用来创建内部变量,使得这些变量不能被外部随意修改,同时又可以通过指定的函数接口来操作
var closure = (function(){ var foo = "foo";
return { getFoo: function() { return foo },
setFoo: function(newFoo){ return foo = newFoo } }
})();
console.log(closure.getFoo()); // foo
console.log(closure.setFoo("newFoo")); // newFoo
console.log(closure.foo); // 获取不到
纯函数
不会产生副作用的函数。
相同的输入,永远会得到相同的输出
//这是个纯函数,满足上面两点条件
const pureFn = function(a,b){ return a + b }
//这个不是存函数,它的副作用就是修改了外部作用域的变量。
let sum = 0;
const plus = (a,b)=>{ sum = a + b;
return sum;
}
函数参数是对象
function test(person) {
person.age = 26
person = { name: 'yyy',
age: 30 }
return person
}
const p1 = { name: 'yck',
age: 25 }
const p2 = test(p1)
console.log(p1) // -> 26 'yck'
console.log(p2) // -> 30 'yyy'
代码解释:
函数传参是传递对象指针的副本,因此函数里面如果修改了对象副本的话,原对象也会跟着修改的
函数里面的person属性被重新赋值一个新对象,因此p2就等于新对象。