函数种类
| 名称 | 写法 | 解释 |
|---|---|---|
| 普通函数 | 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()); // 0console.log(fn()); // 1console.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()); // fooconsole.log(closure.setFoo("newFoo")); // newFooconsole.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 = 26person = { 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就等于新对象。
