四、JavaScript 作用域与作用域链

作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域链的工作原理。

1 作用域

作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。

1.1 变量的作用域

在JavaScript中,变量的作用域有全局作用域和局部作用域两种。

全局作用域(Global Scope):

在代码中任何地方都能访问到的对象拥有全局作用域,一般来说以下几种情形拥有全局作用域:

1) 最外层函数和在最外层函数外面定义的变量拥有全局作用域

2) 所有末定义直接赋值的变量自动声明为拥有全局作用域

3) 所有window对象的属性拥有全局作用域

局部作用域(Local Scope):

和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部,所以这种作用域也称为函数作用域。

样例

var message = "Hello"; //全局作用域

function sayHi(){

    console.log(message);

    var myName = "Castiel_Z"; //局部作用域

    content = "Hello ReactNative"; //全局作用域

}

1.2 函数作用域

 ECMAScript 中只存在一种作用域 - 公用作用域。ECMAScript 中的所有对象的所有属性和方法都是公用的。因此,定义自己的类和对象时,必须格外小心。记住,所有属性和方法默认都是公用的.

由于缺少私有作用域,开发者确定了一个规约,说明哪些属性和方法应该被看做私有的。这种规约规定在属性前后加下划线:

obj._color_ = "blue"; // 注意,下划线并不改变属性是公用属性的事实,只是规约 

1.3 关键字 this

键字 this 总是指向调用该方法的对象,例如:

四、JavaScript 作用域与作用域链_第1张图片
代码片段

在五种不同的情况下 ,this指向的各不相同

1) 全局范围内

this;

当在全部范围内使用this,它将会指向全局对象。

注:浏览器中运行的 JavaScript 脚本,这个全局对象是window。

2) 函数调用

foo();

这里this也会指向全局对象。

注:在严格模式下(strict mode),不存在全局变量。这种情况下this将会是undefined。

3) 方法调用

test.foo();

这个例子中,this指向test对象。

4) 调用构造函数

new foo();

5) 显示设置的this

function foo(a, b, c) {}

var bar = {};

foo.apply(bar, [1, 2, 3]); // 数组将会被扩展,如下所示

foo.call(bar, 1, 2, 3); // 传递到foo的参数是:a = 1, b = 2, c = 3

当使用 Function.prototype 上的 call 或者 apply 方法时,函数内的 this 将会被 显式设置为函数调用的第一个参数。 因此函数调用的规则在上例中已经不适用了,在foo 函数内 this 被设置成了 bar

2 作用域链(Scope Chain)

在JavaScript中,函数也是对象,实际上,JavaScript里一切都是对象。函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性。其中一个内部属性是[[Scope]],由ECMA-262标准第三版定义,该内部属性包含了函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。

特点:"链式作用域"结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。

先简单理解下特点就行了 ^-^!。想深入了解的进参考中的博客。


参考:JavaScript 开发进阶:理解 JavaScript 作用域和作用域链

你可能感兴趣的:(四、JavaScript 作用域与作用域链)