一等公民–函数
在Javascript中函数也是一等公民,函数可以独立存在,声明后就可以直接使用。
let animal = {"name": "animal"};
function eat(animal) {
console.log(animal.name + " is eating")
}
eat(animal);// animal is eating
// 只要一个对象有name这个属性就可以调用
let dog = {"name": "dog"};
let cat = {"name": "cat"};
let person = {"name": "person"};
eat(dog);// dog is eating
eat(cat);// cat is eating
eat(person);// person is eating
函数还可以作为参数传递给另外一个函数
function eat(animal) {
console.log(animal.name + " is eating")
}
function each(list, fun) {
for(let i = 0; i< list.length; i++) {
fun(list[i]);
}
}
let dog = {"name": "dog"};
let cat = {"name": "cat"};
let person = {"name": "person"};
let list = [dog, cat, person];
each(list, eat);
// dog is eating
// cat is eating
// person is eating
函数也可以作为返回值
function createEatFunction(list, fun) {
function eat(animal) {
console.log(animal.name + " is eating")
}
return eat;
}
let dog = { "name": "dog" };
let eat = createEatFunction();
eat(dog);// dog is eating
闭包
function createEatFunction(list, fun) {
var desc = " is eating";
function eat(animal) {
console.log(animal.name + desc)
}
return eat;
}
var desc = "正在吃东西";
let dog = { "name": "dog" };
let eat = createEatFunction();
eat(dog);// dog is eating
eat(dog);输出应该是‘dog is eating’ , 而不是 ‘dog 正在吃东西’。在JavaScript 当中,有个作用域链(scope chain)的东西,它定义了一个函数激活执行的时候去哪儿找变量的值, 比如eat函数的作用域链是这样的(此图只是示意图,并不严谨,例如没有表达出Activation object, Variable Object等概念):
这叫做静态作用域(static scope),或者叫词法作用域(lexical scope)。当eat函数被激活执行,就可以在createEatFuncction中找到desc的值,而不是在全局中找到desc的值。
var x = 1;
function foo() {
console.log(x);
}
function bar(func) {
var x = 2;
func();
}
bar(foo);// 1
由于静态作用域!函数foo在创建的那一刻, 已经确定了它会和包含x=1的全局作用域关联 , 所以在运行的时候也只会从全局l作用域查找,而不是从bar 函数的作用域中找x。
闭包在JavaScript当中就是一个函数和以静态方式存储的父作用域的一个集合体,通过这个集合体,一个函数就可以访问外部函数的变量了。
从 码农翻身 公众号 摘录