执行上下文-作用域链-闭包

1.1 执行上下文-作用域链-闭包

理解 JavaScript 中的执行上下文和执行栈

JavaScript 中有三种执行上下文类型。全局、函数、Eval执行上下文。
在全局执行上下文中,this 的值指向全局对象。(在浏览器中,this引用 Window 对象)。

` 在函数执行上下文中,this 的值取决于该函数是如何被调用的。如果它被一个引用对象调用,那么 this 会被设置成那个对象,否则 this 的值被设置为全局对象或者 undefined(在严格模式下)

1. 立即执行函数

;(function () {
  // 代码
})()
1
2
3

2. 闭包

对于闭包(closure),当外部函数返回之后,内部函数依然可以访问外部函数的变量。

闭包的方法是通过背包的类比, 当一个函数被创建并传递或从另一个函数返回时,它会携带一个背包。
背包中是函数声明时作用域内的所有变量。

3. 使用闭包定义私有变量

通常,JavaScript开发者使用下划线作为私有变量的前缀。但是实际上,这些变量依然可以被访问和修改,并非真正的私有变量。这时,使用闭包可以定义真正的私有变量:

4. prototype

每个JavaScript构造函数都有一个prototype属性,用于设置所有实例对象需要共享的属性和方法。
prototype属性不能列举。JavaScript仅支持通过prototype属性进行继承属性和方法。

5. 模块化

JavaScript并非模块化编程语言,至少ES6落地之前都不是。然而对于一个复杂的Web应用,模块化编程是一个最基本的要求。
这时,可以使用立即执行函数来实现模块化,正如很多JS库比如jQuery以及我们Fundebug都是这样实现的。
所谓模块化,就是根据需要控制模块内属性与方法的可访问性,即私有或者公开。

6. 变量提升

JavaScript会将所有变量和函数声明移动到它的作用域的最前面,这就是所谓的变量提升(Hoisting)。也就是说,无论你在什么地方声明变量和函数,解释器都会将它们移动到作用域的最前面。因此我们可以先使用变量和函数,而后声明它们。

7. 柯里化

柯里化,即Currying,可以是函数变得更加灵活。
我们可以一次性传入多个参数调用它;也可以只传入一部分参数来调用它,让它返回一个函数去处理剩下的参数。

8. apply, call 与 bind 方法

JavaScript开发者有必要理解apply、call与bind方法的不同点。它们的共同点是第一个参数都是this,即函数运行时依赖的上下文。

三者之中,call方法是最简单的,它等价于指定this值调用函数:

apply方法与call方法类似。两者唯一的不同点在于,apply方法使用数组指定参数,而call方法每个参数单独需要指定

使用bind方法,可以为函数绑定this值,然后作为一个新的函数返回:

9. Memoization

Memoization用于优化比较耗时的计算,通过将计算结果缓存到内存中,这样对于同样的输入值,下次只需要中内存中读取结果。
例如,将每个执行结果都存入函数内部作用域中的值中。

10. 函数重载

所谓函数重载(method overloading),就是函数名称一样,但是输入输出不一样。或者说,允许某个函数有各种不同输入,根据不同的输入,返回不同的结果。
凭直觉,函数重载可以通过if…else或者switch实现,这就不去管它了。
jQuery之父John Resig提出了一个非常巧(bian)妙(tai)的方法,利用了闭包。

、、、、 、、、、 、、、、 、、、、 、、、、 、、、、 、、、、 、、、、

上次更新:
(adsbygoogle = window.adsbygoogle || []).push({});