以语言的角度学习 Js 的底层原理(与 DOM 无关):① 作用域链 ② 词法分析 ③ 闭包 ④ 面向对象(原型链)

① 作用域链

例1

<script>
var c = 5;
function t1(){
var d = 6;
function t2(){
var e = 7;
alert(c + d + e);
}
t2();
}
t1();
</script>

弹出:18

首先在函数内寻找变量,如果寻找不到,则往外层寻找,直到全局(window)区域

例2

<script>
var c = 5;
function t1(){
var d = 6;
function t2(){
var e = 7;
var d = 3;
alert(c + d + e);
}
t2();
}
t1();
</script>

弹出:15

寻找变量的顺序是由内向外,变量 d 首先找到了 3 ,从而不会继续向外曾寻找变量 d 。

例3

<script>
alert(window.d);
alert(window.e); function t(){
d = 5;
var e = 6;
}
t(); alert(window.d);
alert(window.e);
</script>

依次弹出:undefined,undefined,5,undefined

d 没有加 var ,仅仅是一个赋值操作,寻找 t 域内的函数,没找到,继续寻找 → window,widow.d = 5(第 3 个 alert)

var 是在函数运行的上下文中,声明一个变量,如果不加 var,则是赋值操作,但不要狭隘地理解为 声明了一个全局变量(见例4)。

例4

<script>
function t1(){
var d;
function t2(){
d = 5;
e = 6;
}
t2();
}
t1();
console.log(d);
console.log(e);
</script>

console 中打印出:Uncaught ReferenceError: d is not defined

如果只

 console.log(e); 

则打印出 6

t2 内部没有 d 变量,仅仅是赋值操作,往外层寻找 d 变量,在t1 函数中找到了,于是把变量 d 的值赋给了 5;

e 也仅仅是赋值操作,并没有相应的变量,因此往外找变量,直到找到最外层(window),还是没有找到,只有 window.e = 6

如果

console.log(window.d);
console.log(e);

则打印出:

undefined
6

注意区别:以 window.*** 引用全局变量时,如果寻找不到,则作为某个属性不存在而返回 undefined;若直接以 *** 引用某变量,寻找不到则是报 *** is undefined 错误。

例5(极容易出错又极基础的面试题)

 <script>
var str1 = 'global';
function t1(){
console.log(str1);
console.log(str2);
str2 = 'local';
}
t1();
</script>

打印出:

global
Uncaught ReferenceError: str2 is not defined

【分析】:

第 4 行在执行时,在 t1 内寻找 str1,没有,于是在 window 上寻找 str1,找到,因此打印'global'

第 5 行在执行时,在 t1 内寻找 str2,没有,于是在 window 上寻找 str2,没有,因此报 str2 is undefined 错误

第 6 行(由于第 5 行出错,实际上执行不到这里),才把全局的 str2 赋值(window.str2 = 'local')

例6(例5 基础上修改:str2 前加 var)

<script>
var str1 = 'global';
function t1(){
console.log(str1);
console.log(str2);
var str2 = 'local';
}
t1();
</script>

打印出:

global
undefined

加了 var ,则声明了一个变量。

【分析】:

js 代码自上而下执行,但是js 代码的整体运行分:① 词法分析 和 ② 运行期,

在自上而下执行之前,先有词法分析过程

在该例中

第 1 步:分析t1 函数:

t1{

  var str2  //分析出 t1 内有 str2 局部变量。此时只是分析有改变量,并没有赋值(未执行),因此 str2 的值是undefined

}

第 2 步:执行 t1 函数:

console.log(str1);    // global

console.log(str2);    // undefined

str2 = 'local';         // 此时str2 的值为 'local'

Javascript 笔记与总结(1-1)作用域的更多相关文章

  1. javascript笔记:javascript的关键所在---作用域链

    javascript里的作用域是理解javascript语言的关键所在,正确使用作用域原理才能写出高效的javascript代码,很多javascript技巧也是围绕作用域进行的,今天我要总结一下关于 ...

  2. [Effective JavaScript 笔记]第3章:使用函数--个人总结

    前言 这一章把平时会用到,但不会深究的知识点,分开细化地讲解了.里面很多内容在高3等基础内容里,也有很多讲到.但由于本身书籍的篇幅较大,很容易忽视对应的小知识点.这章里的许多小提示都很有帮助,特别是在 ...

  3. [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码

    函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...

  4. [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象

    js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...

  5. [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符

    “1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...

  6. [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法

    js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...

  7. 《JavaScript 闯关记》之作用域和闭包

    作用域和闭包是 JavaScript 最重要的概念之一,想要进一步学习 JavaScript,就必须理解 JavaScript 作用域和闭包的工作原理. 作用域 任何程序设计语言都有作用域的概念,简单 ...

  8. javascript 变量 命名规范 变量的作用域

    原文:javascript 变量 命名规范 变量的作用域 大家好,我是小强老师,今天讲解的是变量 变量 小时候我们学过  这个 应用题 :  X+1=2; 问  X 等于几?  答案是 1 对了,很聪 ...

  9. 从头开始学JavaScript 笔记(一)——基础中的基础

    原文:从头开始学JavaScript 笔记(一)--基础中的基础 概要:javascript的组成. 各个组成部分的作用 . 一.javascript的组成   javascript   ECMASc ...

  10. 【原】javascript笔记之Array方法forEach&map&filter&some&every&reduce&reduceRight

    做前端有多年了,看过不少技术文章,学了新的技术,但更新迭代快的大前端,庞大的知识库,很多学过就忘记了,特别在项目紧急的条件下,哪怕心中隐隐约约有学过一个方法,但会下意识的使用旧的方法去解决,多年前ES ...

随机推荐

  1. Android之Activity框架

    在安卓应用中,经常需要Activity中经常需要有大量相似的Activity类,这些类往往有相似的结构与功能,因此产生了大量重复代码,为此,以下提供一种方法有效的降低了代码冗余. 定义Activity ...

  2. 谈谈Objective-C的警告 (转)

    原文地址:http://onevcat.com/2013/05/talk-about-warning/ 一个有节操的程序员会在乎自己的代码的警告,就像在乎饭碗边上有只死蟑螂那样. ——@onevcat ...

  3. Java查询网址

    Java在线帮助文档: http://docs.oracle.com/javase/8/docs/technotes/guides/desc_jdk_structure.html Java小知识讲解: ...

  4. hdu 4002 欧拉函数 2011大连赛区网络赛B

    题意:求1-n内最大的x/phi(x) 通式:φ(x)=x*(1-1/p1)*(1-1/p2)*(1-1/p3)*(1-1/p4)…..(1-1/pn),其中p1, p2……pn为x的所有质因数,x是 ...

  5. 【vijos1659】河蟹王国 线段树<区间修改+区间最大值>

    描述 河蟹王国有一位河蟹国王,他的名字叫羊驼.河蟹王国富饶安定,人们和谐相处.有一天,羊驼国王心血来潮,想在一部分人中挑出最和谐的人.于是,羊驼国王将他的子民排成了一列(==!!b汗~好长呀).每个人 ...

  6. php 批量生成html、txt文件

    首先建立一个conn.php的文件用来链接数据库 <?php     $link = mysql_connect("mysql_host" , "mysql_use ...

  7. servlet中cookie的使用

    ---恢复内容开始--- Cookie是存储在客户端计算机上的文本文件,并保留了它们的各种信息跟踪的目的. Java Servlet透明支持HTTP Cookie. 涉及标识返回用户有三个步骤: 服务 ...

  8. iOS 初步单元测试

    - (void)testExample { // This is an example of a functional test case. // Use XCTAssert and related ...

  9. C#二进制与字符串之间的相互转换

    1 /// <summary> 2 /// 将字符串转成二进制 3 /// </summary> 4 /// <param name="s">& ...

  10. css3中的几何图形shape研究

    前言 估计大家在日常工作中都会用到css形状,但是目前天朝中使用到最多的估计就是圆(circle).椭圆(ellipse).各种三角形形状,但是你肯定很少看见过用几何图形或者多边图形.假如你不懂什么叫 ...