JS(作用域)_关于作用域的注意点

一、前言

最近复习的时候总算是把以前作用域涉及到的模糊的概念弄得差不多了。

以下是几个关于js作用域中重要的概念

二、主要知识

1、Js因为 JavaScript 采用的是静态作用域,函数的作用域在函数定义的时候就决定了。

举例:

 1 var value = 1;
 2
 3 function foo() {
 4     console.log(value);
 5 }
 6
 7 function bar() {
 8     var value = 2;
 9     foo();
10 }
11
12 bar();//1

/*bar()中能访问的有:value=2, foo(), value=1foo()中能访问的有: value=1

*/

说明:由于JS是静态作用域,在函数定义好之后,他的作用域就已经确定了。所以在bar()函数中调用foo()只能访问到value=1.

参考:https://github.com/mqyqingfeng/Blog/issues/3

2、以下三种情况的作用域为全局

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

 1 var authorName="山边小溪";
 2
 3 function doSomething(){
 4
 5     var blogName="梦想天空";
 6
 7     function innerSay(){
 8
 9         alert(blogName);
10
11     }
12
13     innerSay();
14
15 }
16
17 alert(authorName); //山边小溪
18
19 alert(blogName); //脚本错误
20
21 doSomething(); //梦想天空
22
23 innerSay() //脚本错误

(2)i=100; 没有用var关键字,使用直接赋值方式声明的是全局变量。

 1 function doSomething(){
 2
 3     var authorName="山边小溪";
 4
 5     blogName="梦想天空";
 6
 7     alert(authorName);
 8
 9 }
10
11 doSomething(); //山边小溪
12
13 alert(blogName); //梦想天空
14
15 alert(authorName); //脚本错误

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

参考:https://blog.csdn.net/qq_30904985/article/details/81272577

3、关于作用域链

(1)一个函数的活动对象是:他自己的arguments(参数)和 定义在函数内部的变量,然后是父级的活动对象,一层一层往上查找。

4、面试题

(1)

var a = 10;
        var o = {
             a:11,
             b:{
                 fn:function(){
                      console.log(a);
                 }
             }
        }
        o.b.fn(); //10说明:因为fn:function()中的活动对象只有全局的a

(2)

            function foo() {
            console.log(value);
            }

            function bar() {
            var value = 2;
            foo();
            }
            var value = 1;
            bar();//1 说明:foo()中先查找自己的活动对象是否有a, 发现有,直接输出自己活动对象的a=1,          

(3)这种情况与上面有点不同, value=2只有赋值没有定义,所以会被提升到最上面

            //var value = 2
            function foo() {
            console.log(value);
            }
            function bar() {
            value = 2;
            foo();
            }
            var value = 1;
            bar();//2

(4)函数体内函数声明会被提升

1       function a(b){
2             console.log(b);  //函数b
3             function b(){
4                 console.log(b); //函数b
5             }
6             b();
7         }
8         a(1)

上面的代码等效如下:

        function a(b){
             function b(){
                 console.log(b); //函数b
             }
             console.log(b);  //函数b

             b();
         }
         a(1)

(5)

  function fun(num){
            console.log(num); //10
            var num = 5;
            console.log(num); //5
        }
        fun(10)

(6)

 1   function fun(ger){
 2             console.log(ger);
 3             var ger = function(){//函数表达式
 4                 alert("hello world");
 5             }
 6             console.log(ger)
 7         }
 8         fun(5)
 9         //分析一波
10         // 1.分析全局变量GO,生成go对象
11         // GO={
12         //     全局变量声明:
13         //         没有略过
14         //     全局函数声明:
15         //     fun:function;
16         // }
17         // 2.逐行执行
18         // 3.分析AO,生成AO对象
19         // AO={
20         //     1.分析参数
21         //         ger:5
22         //     2.分析变量声明:
23         //         没有略过
24         //     3.分析函数声明
25         //         没有略过
26         //     重复名称覆盖
27         // }
28         // 最后输出:5

(7)

 1  function fun(ger){
 2             console.log(ger);
 3             function ger(){
 4                 alert("hello world");
 5             }
 6         }
 7         fun(5)
 8         //分析一波
 9         // 1.分析全局变量GO,生成go对象
10         // GO={
11         //     全局变量声明:
12         //         没有略过
13         //     全局函数声明:
14         //     fun:function;
15         // }
16         // 2.逐行执行
17         // 3.分析AO,生成AO对象
18         // AO={
19         //     1.分析参数
20         //         ger:5
21         //     2.分析变量声明:
22         //         没有略过
23         //     3.分析函数声明
24         //         ger:function;
25         //     重复名称覆盖
26         // }
27         // 最后输出:function ger(){
28             //     alert("hello world");
29             // }

原文地址:https://www.cnblogs.com/xxm980617/p/11229334.html

时间: 2024-12-28 09:38:32

JS(作用域)_关于作用域的注意点的相关文章

对js中闭包,作用域,原型的理解

前几天,和朋友聊天,聊到一些js的基础的时候,有一种‘好像知道,好像又不不知道怎么讲的感觉’...于是捡起书,自己理一理,欢迎拍砖. 闭包 理解闭包首先要理解,js垃圾回收机制,也就是当一个函数被执行完后,其作用域会被收回,如果形成了闭包,执行完后其作用域就不会被收回. 如果某个函数被他的父函数之外的一个变量引用,就会形成闭包 闭包的作用,就是保存自己私有的变量,通过提供的接口(方法)给外部使用,但外部不能直接访问该变量. 例子(使用闭包): var test=(function(){ var

js没有块级作用域

今天看一篇介绍ECMAscript6的博文时,看到let命令的时候突然有点蒙逼....... let命令:let用于变量声明,与var用法类似,但是let是一个局部变量,只在声明的代码块中有效. { let a = 10; var b = 20; } a // not defined b // 20 看到这我觉得这个块级作用域是函数作用域,但是块级作用域和函数作用域是不一样的,比如: function demo(){ var a=1; } console.log(a); a//not defin

深入理解JS中的变量作用域

在JS当中一个变量的作用域(scope)是程序中定义这个变量的区域.变量分为两类:全局(global)的和局部的.其中全局变量的作用域是全局性的,即在JavaScript代码中,它处处都有定义.而在函数之内声明的变量,就只在函数体内部有定义.它们是局部变量,作用域是局部性的.函数的参数也是局部变量,它们只在函数体内部有定义. 我们可以借助JavaScript的作用域链(scope chain)更好地了解变量的作用域.每个JavaScript执行环境都有一个和它关联在一起的作用域链.这个作用域链是

C++ Primer 学习笔记_17_类与数据抽象(3)_类作用域

C++ Primer 学习笔记_17_类与数据抽象(3)_类作用域 引言: 每个类都定义了自己的新作用域与唯一的类型.即使两个类具有完全相同的成员列表,它们也是不同的类型.每个类的成员不同与任何其他类(或任何其他作用域)的成员. 一.类作用域中的名字查找 1)首先,在使用该名字的块中查找名字的声明.只考虑在该项使用之前声明的名字. 2)如果在1)中找不到,则在包围的作用域中查找. 如果找不到任何声明,则出错. 类的定义实际上是在两个阶段中处理: 1)首先,编译器声明: 2)只有在所有成员出现之后

js变量以及其作用域详解

一.变量的类型  Javascript和Java.C这些语言不同,它是一种无类型.弱检测的语言.它对变量的定义并不需要声明变量类型,我们只要通过赋值的形式,可以将各种类型的数据赋值给同一个变量.例如: i=100;//Number类型 i="variable";//String类型 i={x:4};//Object类型 i=[1,2,3];//Array类型 JS的这种特性虽然让我们的编码更加灵活,但也带来了一个弊端,不利于Debug,编译器的弱检测让我们维护冗长的代码时相当痛苦. 二

6个函数的output看JS的块级作用域

1. var output = 0; (function() { output++; }()); console.log(output); 函数对全局的output进行操作,因为JS没有块级作用域,所以output为1. 2. var output = 0; (function(output) { output++; }(output)); console.log(output); 函数传入output的值,但函数内只是对参数output做加一操作,没有对全局的output进行操作,所以outp

js 中采用词法作用域

所谓的 词法( 代码 )作用域, 就是代码在编写过程中体现出来的作用范围. 代码一旦写好, 不用执行, 作用范围就已经确定好了. 这个就是所谓词法作用域. 在 js 中词法作用域规则: 1.函数允许访问函数外的数据. 2.整个代码结构中只有函数可以限定作用域. 3.作用规则首先使用提升规则分析. 4.如果当前作用规则中有名字了, 就不考虑外面的名字. 在编译语言中,**通常** 代码在被引擎执行之前会经历三个步骤: 1. 词法分析(tokenzing/lexing)2. 解析/语法分析(pars

js:深入闭包(作用域:下)

函数功能:该函数将一个字符串转为字形下标的数组.此函数可用来确定一种字体里是否存在某个字形 控制台下代码: #include "stdafx.h" #include <windows.h> #include"stdio.h" void main() { char ch[] = {'0'}; WORD chnl[20] = {0}; HDC hdc; hdc = GetWindowDC(0); int n = GetGlyphIndicesA(hdc,ch

js没有块级作用域但有函数作用域

任何一对花括号中的语句集都属于一个块,在这之中定义的所有变量在代码块外都是不可见的,我们称之为块级作用域. 作用域永远都是任何一门编程语言中的重中之重,因为它控制着变量与参数的可见性与生命周期.首先我们理解两个概念:块级作用域与函数作用域. 什么是块级作用域呢? 任何一对花括号({和})中的语句集都属于一个块,在这之中定义的所有变量在代码块外都是不可见的,我们称之为块级作用域. 函数作用域就是定义在函数中的参数和变量在函数外部是不可见的. 大多数类C语言都拥有块级作用域,JS却没有.请看下文de