函数的作用域
指的是属于这个函数的全部变量都可以在整个其范围内使用以及 复用。
- 函数隐藏的内部实现
将函数和函数隐藏,符合软件开发中的最小暴露原则,比如一些api的设计,它的好处 就是1)规避冲突,可以规避同名标识符;2)现在的模块管理器的实现作为我们模块化开发的工具。 - 函数和函数 表达式的区别:
是 他们的名称标识符将会绑定在何处,函数表达式将函数绑定在()内。 - 匿名函数(没有函数名称的表达式,像立即执行函数,定时器)
特点1:匿名函数在栈追踪不会 显示出有意义的函数 名字,使得调试 很困难
如果 没有函数名字,当函数要引用自身的时候,智能使用过期的arguemnts.calle引用,比如在递归中
特点2:忽略了代码的可读性
作用域快
if和普通 for循环作用域块的定义的变量会暴露到全局
然而let是将,将 i重新绑定到循环的每一个迭代中,确保每一个循环结束时候重新 赋值。
其实就是
{
let j;
for(j=0,i<10,j++){
let i= j;每个迭代重新绑定;
}
}
补充:
- 声明提升,函数优先
只有函数声明本身会被提升,而赋值或者其他 逻辑会留在原地。
函数声明和变量的声明都会被提升 ,但是函数首先被提升,其次才是变量。
- 闭包
词法无论 通过任何手段j将内部的函数传递到词法作用域以外,会持有原始作用域的 引用,无论何时使用这函数都会使用闭包。
了解一下词法作用域的
1:作用域的两种工作模型:
(1)词法作用域(大多数编程语言采用)–》定义在词法阶段的作用域。
那么什么是此法阶段
大部分标准语言编译器第一个工作 阶段就是叫做词法化,对源码中的字符进行检查,如果有状态解析过程,还会赋予单词予以。
(2)动态作用域
2:创建一个函数就会创建一个新的气泡作用域,作用域气泡是根据函数结构逐级包含。
3:引擎的查找
作用域气泡的结构和相互关系给了引擎足够的位置信息从而查找。
假如有以下两个函数作用域
function outer(){
var a = 2;
function inner(){
var a = 5;
console.log(a)//5a—?
}
}
作用域查找会在找到第一个标识符后停止,叫做遮蔽效应。
接下来介绍欺骗词法
如果说词法作用域完全由写代码时候的函数声明位置决定,怎么来修改这个作用域?
1:eval
首先eval函数接受一个字符串的参数
作用:将字符串中的语句当作代码执行。
2:with
with通常被重复引用同一个对象中的多个属性的快捷方式,可以不需要重复引用对象本身。
总结:
with和eval创建作用域的时候改变其他变量和函数定义的词法作用域,
js引擎在编译阶段进行的数据性能优化,某些优化依赖变量和函数的位置可以快速找到,但是eval和with的情况引擎无法识别