一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。
函数是一等公民
在JavaScript中,你可以将一个函数赋值给一个变量,还可以将函数作为一个参数传递给另外一个函数,甚至可以使得一个函数返回一个另外一个函数,这在很多主流语言里都是很难实现的。
在JavaScript中,函数如此灵活的根本原因就在于JavaScript中的函数就是一种特殊的对象。
基于这种设计,js非常容易实现一些特性,比如闭包,还有函数式编程。
什么是JavaScript对象
JavaScript是一门基于对象(Object-Based)的语言,大部分内容都是由对象构成。
JavaScript实现继承,只是在对象中添加了一个称为原型的属性,把继承的对象通过原型链连接起来,从而实现继承。
对象就是一组属性和值的集合。
对象分为三种类型,
第一种是原始类型,包括null,undefined,boolean,number,string,bigint,symbol
第二种就是对象类型
第三种就是函数类型
函数的本质
函数就是一种特殊的对象,和对象一样拥有key和value,但是函数和普通对象不同的是,函数可以被调用。
在v8内部,会给函数对象添加两个隐藏属性,name属性和code属性。
name属性就是函数名称,如果某个函数没有设置函数名,那name的value就是anonym,另外一个隐藏属性就是code,其值表示为函数代码,执行函数调用语句的时候,v8便会从函数对象中取出code属性值,也就是函数代码,然后在解释执行这段代码。
为什么函数是一等公民
因为函数是一种特殊的对象,所以在JavaScript中,函数可以赋值给一个变量,也可以作为函数的参数,还可以作为函数的返回值,如果某个编程语言的函数可以和它的数据类型做一样的事情,我们就把这个语言中的函数称之为一等公民。
在执行JavaScript函数过程中,为了实现变量的查找,V8维护了一个作用域链,如果函数中使用了某个变量,但是在函数内部又没有定义该变量,那么函数就会沿着作用域链去外部的作用域中查找该变量。
function foo(){
let num=1
function bar(){
num++
console.log(num)
}
}
let mybar=foo()
mybar
我们在foo函数中定义了一个新的bar函数,bar函数引用了外部函数中的变量number。调用foo函数,返回bar函数
如果返回bar函数给外部,那么foo函数执行完number变量不能被销毁,因为bar引用了这个变量,这种将外部变量和函数绑定起来的技术称为闭包。
\