关于JavaScript作用域你想知道的一切

Javacript 中有一系列作用域的概念。对于新的JS的开发人员无法理解这些概念,甚至一些经验丰富的开发者也未必能。这篇文章主要目的帮助理解JavaScript中的一些概念如:scope,closure, this, namespace, function scope, global scope, lexical scope and public/private scope. 希望从这篇文章中能回答如下的问题:

什么是作用域(scope)?

什么是全局(Global)和局部(Local)作用域?

什么是命名空间和作用域的区别?

什么是this关键字且作用域对其的影响?

什么是函数作用域、词汇作用域?

什么是闭包?

什么是公有和私有作用域?

如何理解和创建上述内容?

1、什么是作用域( Scope)?
JavaScript中,作用域通常是指代码的上下文(context)。能够定义全局或者局部作用域。理解JavaScript的作用域是编写强健的代码和成为一个好的开发者的前提。你需要掌握在那里获取变量和函数,在那里能够能够改变你的代码上下文的作用域以及如何能够编写快速和可读性强以及便于调试的代码。

想象作用域非常简单,我们在作用域A还是作用域B?

2、什么是全局作用域( Global Scope)?
在写第一行JavaScript代码之前,我们处在全局作用域中。此时我们定义一个变量,通常都是全局变量。

// global scopevar name = 'Todd';

全局作用域即是你的好友又是你的噩梦。学习控制作用域很简单,学会后使用全局变量就不会遇到问题(通常为命名空间冲突)。经常会听到大伙说 “全局作用域不好”,但是从没有认真想过为什么。不是全局作用域不好,而是使用问题。在创建跨作用域Modules/APIs的时候,我们必须在不引起问题的情况下使用它们。

jQuery('.myClass');

...我们正在全局作用域中获取jQuery,我们可以把这种引用称为命名空间。命名空间通常是指作用域中可以交换word,但是其通常引用更高级别的作用域。在上面的例子中,jQuery 在全局作用域中,也称为命名空间。jQuery 作为命名空间定义在全局作用域中,其作为jQuery库的命令空间,库中的所有内容成为命名空间的子项(descendent )。

2、什么是局部作用域( Local Scope)?
局部作用域通常位于全局作用域后。一般来说,存在一个全局作用域,每个函数定义了自己的局部作用域。任何定义于其他函数内部的函数都有一个局部作用域,该局部作用域链接到外部函数。
如果定义了一个函数并在里面创建变量,那么这些变量就是局部变量。例如:

// Scope A: Global scope out here var myFunction = function () { // Scope B: Local scope in here};

任何的局部作用变量对全局变量来说是不可见的。除非对外暴露。如在新的作用域内定义了函数和变量,他们为当前新作用域内的变量,不能够在当前作用域外被访问到。下面为一个简单的说明示例:

var myFunction = function () { var name = 'Todd'; console.log(name); // Todd}; // Uncaught ReferenceError: name is not defined console.log(name);

变量name为局部变量,没有暴露给父作用域,因此出现not defined。

3、函数作用域
JavaScript 中函数域为最小域范围。for与while循环或者if和switch都不能构建作用域。规则就是,新函数新域。一个创建域的简单示例如下:

// Scope A var myFunction = function () { // Scope B var myOtherFunction = function () {// Scope C};};

非常方便的创建新的域和本地变量、函数和对象。

4、词汇作用域( Lexical Scope)
当遇到一个函数嵌套到另一函数中,内部函数能够访问外部函数的作用域,那么这种方式叫做词汇作用域(Lexical Socpe)或者闭包,也称为成为静态作用域。最能说明该问题的示例如下:

// Scope A var myFunction = function () { // Scope B var name = 'Todd'; // defined in Scope B var myOtherFunction = function () { // Scope C: `name` is accessible here!}; };

这里只是简单的定义了myOtherFunction,并没有调用。这种调用顺序也会影响变量的输出。这里我在另一控制台中再定义和调用一个函数。

var myFunction = function () { var name = 'Todd'; var myOtherFunction = function () { console.log('My name is ' + name); }; console.log(name); myOtherFunction(); // call function }; // Will then log out:// `Todd` // `My name is Todd`

词汇作用域用起来比较方便,任何父作用域中定义的变量、对象和函数在其域作用链中都可以使用。例如:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgwwgf.html