赋值

深入理解js——执行上下文

拈花ヽ惹草 提交于 2020-02-11 05:14:42
什么是“执行上下文”?暂且不下定义,先看一段代码: 第一句报错,a未定义,很正常。第二句、第三句输出都是undefined,说明浏览器在执行console.log(a)时,已经知道了a是undefined,但却不知道a是10(第三句中)。 在运行一段js代码之前,浏览器已经做了一些“准备工作”,其中就包括对变量的声明,而不是赋值。变量赋值是在赋值语句执行的时候进行的。可用下图模拟: 这是第一种情况。 第二种情况。 有js开发经验的朋友应该都知道,你无论在哪个位置获取this,都是有值的。至于this具体的取值情况,那就比较复杂了。与第一种情况不同的是:第一种情况只是对变量进行声明(并没有赋值),而此种情况直接给this赋值。这也是“准备工作”情况要做的事情之一。 第三种情况。 需要注意代码注释中的两个名词——“函数表达式”和“函数声明”。虽然两者都很常用,但是这两者在“准备工作”时,却是两种待遇。 在“准备工作”中, 对待函数表达式就像对待“ var a = 10 ”这样的变量一样,只是声明。而对待函数声明时,却把函数整个赋值了 。 好了,“准备工作”介绍完毕。 我们总结一下,在“准备工作”中完成了哪些工作: 变量、函数表达式——变量声明,默认赋值为undefined; this——赋值; 函数声明——赋值; 这三种数据的准备情况我们称之为“执行上下文”或者“执行上下文环境”。

Execution Context(EC) in ECMAScript

為{幸葍}努か 提交于 2020-02-11 03:57:04
参考资料 执行环境,作用域理解 深入理解JavaScript系列(2):揭秘命名函数表达式 深入理解JavaScript系列(12):变量对象(Variable Object) 深入理解JavaScript系列(14):作用域链(Scope Chain) 深入理解JavaScript系列(13):This? Yes,this! 代码的执行所处的环境,也叫执行上下文,它确定了代码的作用域,作用域链,this属性,代码的生存期等等,让我们从 解释器的角度 看代码是如何执行的。 EC可以用如下的数据结构表达,它有很多属性,VO,[[scope]],this等等。 EC={ Variable Object:...., [[scope]]:..., this:... } 1 三种EC(代码执行环境) global function eval 2 代码执行的过程 一段JS代码进入解释器到执行分为2步骤,这2步各自有各自的事要处理 进入执行环境 执行代码 3 Variable Object(VO) 我们声明的变量, 声明的函数 ,传入的参数都放到哪里去了?引擎是在哪里寻找它们的?其实它们都放入到一个叫VO的对象里去了,可以说了解VO是很重要的。VO的数据结构可以如下表达 VO={ 声明的变量, 声明的函数, 参数(函数内部VO拥有) } 3.1 函数的声明与表达式 函数声明式:function

理解JavaScript执行环境(Execution Context)

怎甘沉沦 提交于 2020-02-11 03:49:35
理解JavaScript执行环境(Execution Context) 1.概念 执行环境(Execution Context)是一个抽象的概念,用于规定ECMAScript实现时要求的行为。ECMAScript规范没有指明任何关于如何实现execution context,但是execution context包含参考在规范定义的结构的相关属性,所以execution context可 以被设想成(甚至被实现)带有属性(虽然这些属性不是public属性)的对象。 2.分类 所有的JavaScript代码都是在execution context中执行的。全局代码(内置的执行代码,通常作为一个JS文件或HTML页面加载)在全局execution context中执行,每一个函数(可能作为一个构造函数)调用都有与之关联的execution context。 通过eval函数执行的代码也有一个完全不同的execution context,但因为JavaScript程序员在通常情况下不会使用eval函数,所以这里不作讨论。 3.Execution context栈 当一个函数被调用时,此函数就会进入一个execution context,如果另一个函数被调用(或递归地调用相同的函数),就会创建一个新execution context,在函数调用时一直在此execution

JS 预编译

强颜欢笑 提交于 2020-02-11 01:07:00
第一步: 语法分析 第二步: 预编译 第三步: 解释执行   1. 语义分析     语义分析是通篇执行的一个过程。不如有一篇代码,在执行时是解析一行执行一行,但在执行之前系统执行的第一步它会扫描一遍,看看有没有低级的语法错误,比如少些个符号,带个特殊字符之类的。此时通扫一遍,但是不执行,这个通篇扫面的过程叫语义分析,通篇扫面后就会预编译,然后解释一行执行一行,也就是解释执行。   2. 预编译      1. imply global :暗示全局变量:即任何变量,如果变量未经声名就赋值,自变量就为全局对象所有 a = 10; // 这种应该就是 imply global 了 console.log(a); // 打印 10 window.a; // 10 说明 window 属性上有 a var b = 20; // 声名了 b, 此时 window 也有了 b     2. 一切声名的全局变量,全是 window 的属性     3. 函数声名提升:如果写了一个函数声名,无论写在哪里,浏览器都会把这个函数提到逻辑的最前面。 函数声名整体提升      4. 变量 声名提升 所以系统只提升变量,而不是变量带着值一起提 var a = 123; // 上面的变量声名分为两步 var a; // 第一步,声名变量 a = 123; // 第二步, 变量赋值 console.log(a

JS预编译

白昼怎懂夜的黑 提交于 2020-02-10 23:10:19
JS预编译 js运行三部曲 语法分析 预编译 解释执行 ** 预编译 ** 预编译发生在函数执行前的一刻。 简单现象:函数声明整体提升, 变量 声明提升(定义赋值不提升) ** 预编译过程(四部曲):** 1.创建AO对象(Activated Object)(执行期上下文) 2.找形参和变量声明,将变量和形参名作为AO属性名,值为undefined。 3.将实参值和形参统一。 4.在函数体里面找函数声明,值赋予函数体。 function fn(a){ console.log(a); var a =123; console.log(a); function a(){}; console.log(a); var b = function(){}; console.log(b); function d(){}; } fn(1); //解析 一、预编译过程: 1.创建AO对象,找形参和变量声明,将变量和形参名作为AO属性名,值设置为undefined。 AO{ a:undefined, b:undefined, } 2.形参和实参统一 AO{ a:1, b:undefined, } 3.找函数声明,值赋予函数体 AO{ a:function a(){}, b:undefined, d:function d(){}; } 二、执行过程 1.第一个console.log(a):function

C++ 拾遗

眉间皱痕 提交于 2020-02-10 19:29:24
一、c++两个基本的运算符: &(取址运算符) 和 *(间接访问运算符/解引用指针) 首先是&运算符:当它后面跟一个变量名的时候,给出这个变量名的地址. #include <iostream> using namespace std; int main() { int a=5,b=6,c=7,d=8; double e=3.1415; //单独赋值,并且*和p_a紧挨着 int *p_a=&a; //多个赋值(既有指针,又有普通变量) int * p_b=&b,* p_c=&c,*p_d=&d,temp=100; //单独赋值,double类型 double * p_e=&e; } 二、指针和引用的定义和性质区别: (1)指 针是一个变量,只不过这个变量存储的是一个地址 ,指向内存的一个存储单元;而 引用跟原来的变量实质上是同一个东西 ,只不过是原变量的一个 别名 而已。如: int a=1;int *p=&a; int a=1;int &b=a; (2)可以有const指针,但是没有const引用; (3) 指针可以有多级 ,但是引用只能是一级(int **p;合法 而 int &&a是不合法的) (4)指针的值可以为空,但是引用的值不能为NULL,并且引用在定义的时候必须初始化; (5)指针的值在初始化后可以改变,即指向其它的存储单元,而 引用在进行初始化后就不会再改变 了。

java

纵饮孤独 提交于 2020-02-10 06:58:36
一、基本语法 1.关键字:有特殊含义特殊用途的单词。 2.保留字:事先定义好的,暂时没有特殊用途。 3.标识符:定义的名称,不能使用关键字,见名知意 4.注释:单行//,多行/* */ ,文档/** */ 注释不会被编译到字节码 5.常量:整数、小数、字符‘ ’、字符串“ ”、布尔类型false true、Null常量 不能输出 6.print打印不会换行 printf打印自动换行 输出小数自动除去小数末尾的0 二。变量与数据类型 1.字符串拼接后仍是字符串类型,使用+拼接 2.默认:整型int 浮点型double 3.float 赋值后数字后面加f,long加L 4.数据类型转换: 只能把占用内存小的赋值给大的,不能直接把大的类型赋值给小的类型 5.强制类型转换,会造成数据溢出(数据不正确) (类型)变量名/数值 6.自动类型转换 运算时运算两端的数据类型要保持一致; 如果运算都为数字类型,会将小的类型转化为大的类型(自动类型转换) JVM在运算时识别的最小类型为int,byte short char会提升为int 来源: https://www.cnblogs.com/211806398luguiying/p/10964302.html

python命名空间与作用域

寵の児 提交于 2020-02-10 02:03:33
命名空间是名称与对象之间的关系,可以将命名空间看做是字典,其中的键是名称,值是对象。 命名空间不共享名称。 在命名空间中的名称能将任何python对象作为值,在不同的命名空间中相同的名称可以与不同的对象相关联。但是,如果存在名称解析协议,则多个命名空间可以一起工作来解析名称。也就是说,如果有多个命名空间(总是有的),那么可以定义搜索的顺序,依次在不同的命名空间里来查找某个名称(或确认其不存在于任何认可的命名空间)。在python中,将这一过程定义为作用域。 作用域搜索规则:LEGB L:局部的(local) E:封闭的(Enclosing) G:全局的(Global) B:内置的(Built-in) 一、局部命名空间 函数内部的命名空间,在调用函数的时候生成,调用结束时消失。当局部命名空间有效时,它是第一个用于检查某个名字存在性的命名空间。如果在局部命名空间内找到该名称,则返回与名字相关联的对象,反之提示出错。 二、全局命名空间 python在模块中维护命名空间,模块是一些python文件--包含函数等对象,并且可以导入其他程序使用。当某个模块被导入之后,该模块同时引入了一个命名空间,其中包含模块中所有的名称和关联的对象,可以通过存储在没个模块中的__dict__来查看这个命名空间,换句话说,字典就是这个模块的命名空间。 如果想要引用给模块中的对象,要使用点符号将名称和模块名称关联

python的命名空间

我们两清 提交于 2020-02-10 01:59:20
Python的命名空间是Python程序猿必须了解的内容,对Python命名空间的学习,将使我们在本质上掌握一些Python中的琐碎的规则。 接下来我将分四部分揭示Python命名空间的本质:一、命名空间的定义;二、命名空间的查找顺序;三、命名空间的生命周期;四、通过locals()和globals() BIF访问命名空间 重点是第四部分,我们将在此部分观察命名空间的内容。 一、命名空间 Python使用叫做命名空间的东西来记录变量的轨迹。命名空间是一个 字典(dictionary) ,它的键就是变量名,它的值就是那些变量的值。 A namespace is a mapping from names to objects. Most namespaces are currently implemented as Python dictionaries。 在一个 Python 程序中的任何一个地方,都存在几个可用的命名空间。 1、每个函数都有着自已的命名空间,叫做局部命名空间,它记录了函数的变量,包括函数的参数和局部定义的变量。 2、每个模块拥有它自已的命名空间,叫做全局命名空间,它记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量。 3、还有就是内置命名空间,任何模块均可访问它,它存放着内置的函数和异常。 二、命名空间查找顺序 当一行代码要使用变量 x 的值时

python 语言特性

空扰寡人 提交于 2020-02-10 01:57:38
动态强类型: 动态类型语言:在运行期进行类型检查的语言,也就是在编写代码的时候可以不指定变量的数据类型,比如Python和Ruby 静态类型语言:它的数据类型是在编译期进行检查的,也就是说变量在使用前要声明变量的数据类型,这样的好处是把类型检查放在编译期,提前检查可能出现的类型错误,典型代表C/C++和Java 强类型语言,一个变量不经过强制转换,它永远是这个数据类型,不允许隐式的类型转换。举个例子:如果你定义了一个double类型变量a,不经过强制类型转换那么程序int b = a无法通过编译。典型代表是Java。 弱类型语言:它与强类型语言定义相反,允许编译器进行隐式的类型转换,典型代表C/C++。 Python四种namespace: 通俗的来说,Python中所谓的命名空间可以理解为一个容器。在这个容器中可以装许多标识符。不同容器中的同名的标识符是不会相互冲突的。理解python的命名空间需要掌握三条规则: 第一,赋值(包括显式赋值和隐式赋值)产生标识符,赋值的地点决定标识符所处的命名空间。 第二,函数定义(包括def和lambda)产生新的命名空间。 第三,python搜索一个标识符的顺序是"LEGB"。 所谓的"LEGB"是python中四层命名空间的英文名字首字母的缩写。 最里面的一层是L(local),表示在一个函数定义中,而且在这个函数里面没有再包含函数的定义。