JavaScript面向对象和高级04
来源:互联网 发布:免费手机qq群发软件 编辑:程序博客网 时间:2024/06/05 18:19
词法作用域和作用域链
1 词法作用域
1.1 什么是作用域
作用域,即 起作用的区域。变量定义后,可以在哪个范围内使用该变量
1.2 两种作用域
- 词法作用域
- 块级作用域(JavaScript不支持,了解)
块级作用域:用一个块(代码块)结构限制变量的访问区域。即,块内的每一段代码都有各自的作用域,变量在声明它们的代码段之外是不可见的。代表语言: C 语言( C系,如:Java、Object-C、C#)
- 案例:
for(var i = 0; i < 10; i++) { console.log(i);}alert(i);
1.3 词法作用域
变量的作用范围, 在书写代码的时候就已经决定, 与运行时无关。即,它们在定义它们的作用域里运行,而不是在执行它们的作用域里运行。分割作用域的只有函数,也就是说只有函数 才会形成 作用域。当定义了一个函数,当前的作用域链就保存起来,并且成为函数的内部状态的一部分。
- 面试题
// 1function foo() { var num = 123; console.log(num); // 123}foo();console.log(num); // 报错: num is not defined// 2var scope = "global";function foo() { console.log(scope); // undefined var scope = "local"; console.log(scope); // local}foo();// 3if("a" in window){ var a = 10;}alert(a); // ? 10if(!"a" in window){ var a = 10;}alert(a); // ? undefined// 4var foo = 1;function bar() { if(!foo) { var foo = 10; } alert(foo); // 10}bar();// 4 提升完之后的结果var foo;function bar() { // var foo; // if(!foo) { // foo = 10; } alert(foo); // }foo = 1;bar();
1.3.1 变量提升和函数提升(hoisting)
- JavaScript的执行过程
JS运行的两个步骤:解析和执行1 预解析(不是在执行代码)。 将所有的声明都加载到内存中,也就是:告诉解释器有什么东西了2 一步一步的执行代码, 按照从上往下的顺序
- 变量提升的是:变量的声明
函数提升的是:整个函数
案例和练习
// 2 变式if("b" in window) { var a = 10;}alert(a); // ?undefined// 3if(true) { function f() { alert("true"); }} else { function f() { alert("false"); }}f();// ? 不确定,会根据不同浏览器实现不同// 4if(true) { var f = function () { alert("true"); }} else { var f = function () { alert("false"); }}f();// ? true
- 函数表达式
函数表达式中 可以省略函数名字,如果有函数名字,那么这个函数名只能在函数内部使用。(IE8 除外)函数声明不允许出现在其他语句
2 作用域链
2.1 作用域结论
- 1 声明会提升
- 2 只有函数才会限定作用域,即:函数作用域
2.2 作用域链是什么
每个函数都会形成一个作用域,如果函数被其他函数包裹,包裹函数也有作用域,一直往上直到全局环境。这样就形成了一条作用域链。
- 多个函数才会形成作用域链吗?
// 分析以下函数的作用域链var a = 11;function outer() { var num = 123; function inner() { var str = "abc"; }}// 函数outer的作用域链: 函数自身 -> 全局环境
2.3 绘制作用域链规则
1 将全部的 script 标签看做一个整体,是一个 0 级别的链2 由于只有函数才可以限定作用域,因此在函数上引出一条新链, 级别为 n + 13 如果有函数,继续绘制下去 注意点:1 链中的成员包括:在该链所属范围内 *声明* 的变量, 函数, 对象... 2 由于提升机制的存在,在开始的时候将 声明 都写在前面, 绘图的时候按照顺序绘制, 较为简单3 先绘制链中的成员,其他赋值操作,等到代码执行的时候再看。4 各链之间互不影响
- 案例:
// 1var num = 123;var f = function() {};var arr = [];// 2var num = 123;var f = function() { var num = 456; var o = {}; var foo = function() {};};var arr = [];
2.4 变量搜索原则
在代码的运行过程中, 如果访问某一个变量,那么:1 首先在当前链上找 如果有,则停止查找 如果没有, 在 n-1 级上找( 在函数内部允许访问定义在函数外部的变量 )2 如此往复, 直到 0 级链 如果找到, 则结束寻找, 直接获得该链上变量的数据 如果还没有 抛出异常。
- 案例:
var num = 456;function f() { num = 678; function foo() { var num = 999; console.log(num); // } foo(); console.log(num); // }f();
2.4.1 函数名和变量名同名的问题
如果一个函数和一个变量出现同名,此时:1 如果是变量只声明了,但没有赋值,变量名会被忽略var f;function f() {}console.log(f); // f指的是函数2 如果变量声明同时也被赋值了,此时: a 如果是在赋值之前,获取到的是函数 b 如果是在赋值之后,获取到的是变量的值console.log(f); // function f() {}var f = 123;function f() {}console.log(f); // 123
- 两个变量命名冲突
重复的var声明无效,会被忽略,只会起到赋值的作用var f = 123;var f = 456;var f = 123;f = 456;
6 作用域面试题分析
- 面试题分析:
function Foo() { getName = function(){ alert(1); }; return this; }Foo.getName = function() { alert(2); };Foo.prototype.getName = function(){ alert(3); };var getName = function() { alert(4); };function getName(){ alert(5); }Foo.getName(); // ? 2getName(); // ? 4Foo().getName(); // ? 1getName(); // ? 1new Foo.getName(); // ? 2new Foo().getName(); // ? 3new new Foo().getName(); // ? 3
- 面试题-1
var num = 123;function f1() { console.log(num);}function f2() { var num = 456; f1();}f2(); // ? 123
- 面试题1-变式
var num = 123;function f1(num) { console.log(num); // 456}function f2() { var num = 456; f1(num);}f2();
- 面试题1-变式
var num = 123;function f1() { console.log(num); // 456}f2();function f2() { num = 456; f1();}console.log(num); // 456
- 面试题2-练习
(function (a) { console.log(a); var a = 10; function a(){}}( 100 ));
补充
函数参数跟函数体内部的变量重名的情况:1 参数 首先被提升2 如果是声明的变量没有赋值(或者在赋值之前就打印这个变量的值),此时值为: 传进来的 实参的值3 如果是声明的函数,此时函数会把同名的参数覆盖,此时值为: 函数4 如果函数内部声明都没声明,此时值为:实参的值
阅读全文
1 0
- JavaScript面向对象和高级04
- JavaScript面向对象和高级01
- JavaScript面向对象和高级02
- JavaScript面向对象和高级03
- JavaScript面向对象和高级05
- JavaScript面向对象和高级06
- JavaScript面向对象和高级07
- javascript高级面向对象
- Javascript 高级面向对象
- JavaScript高级面向对象
- javascript 高级面向对象
- JavaScript面向对象高级
- 回顾JavaScript高级面向对象
- 【javascript】javascript之面向对象高级特性
- JavaScript高级程序设计【面向对象-创建对象】
- 《Javascript高级程序设计》面向对象的程序设计
- JavaScript高级程序设计【面向对象-属性类型】
- JavaScript高级程序设计【面向对象-继承】
- 基于windows10下的tensoflow离线与在线安装
- javaweb中关于重定向无法传递中文参数的问题
- setAttribute()与getAttribute()
- AOP事务不回滚的有关问题
- GYP,GN和Ninja
- JavaScript面向对象和高级04
- Linux查看动态链接库的所有函数以及在动态链接库查找某一个函数的方法
- 今日头条 CEO 张一鸣:面试了 2000 个年轻人,混得好的都有这 5 种特质
- caffe---create自己的数据出现的各种bug
- JavaScript面向对象和高级05
- web-侧边栏
- Entity Framework Code First使用DbContext查询
- 基于JsonObject的消息载体JsonObjectResult
- 利用反射取得泛型的类名和属性名