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=1
foo()中能访问的有: 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 // }
虽然现在走得很慢,但不会一直这么慢