作用域是什么
编译原理
-
分词/词法分析
- 这个过程会将由字符组成的字符串分解成(对编程语言来说)有意义的代码块,这些代码块被称为词法单元
-
解析/语法分析
- 词法单元流(数组)转换成一个由元素逐级嵌套所组成的代表了程序语法结构的树(抽象语法树AST)
-
代码生成
- 将AST转换为可执行代码的过程称被称为代码生成
理解作用域
-
处理成员
引擎——负责代码编译和执行
编译器——词法-语法-代码生成
作用域——根据名称查找变量的一套规则
-
引擎查询(代码执行前)
-
一个赋值操作的LHS(左侧)和RHS(右侧)查询
var a = 0 LHS-a,RHS-0 console.log(a) LHS-无,RHS-log和a
如果查找的目的是对变量进行赋值,就会使用LHS查询
如果查找的目的是获取变量的值,就会使用RHS查询
-
词法作用域
词法阶段
定义在词法阶段的作用域,由你在写代码时将变量和块作用域写在哪里来决定的,执行时不变,因此该词法作用域属于静态作用域(相对于动态作用域)
无论函数在哪里被调用,也无论它如何被调用,它的词法作用域都只由函数被创建时所处的位置决定
词法作用域是在写代码或者说定义时确定的,而动态作用域是在运行时确定的(javascript的this也是)
词法作用域关注函数在何处声明,而动态作用域关注函数从何处调用
欺骗词法
eval——修改词法
with——创建词法
-
性能
处于运行时才确定的eval和with的使用会导致代码运行变慢
引擎无法在编译时对其作用域查找进行优化,因此只能谨慎地认为这样的优化是无效的
函数作用域和块作用域
块作用域
with:用with从对象中创建出的作用域仅在with声明中而非外部作用域中有效
try/catch:try/catch的catch分句会创建一个块作用域,其中声明的变量仅在catch内部有效(性能糟糕)
ps:任何声明在某个作用域内的变量,都将附属于这个作用域
提升
-
js引擎会将"var a = 2"当作两个单独的声明
第一个是编译阶段的任务(var a=undefined)
第二个则是执行阶段的任务(a=2)
作用域闭包
在自身的作用域外被调用并使得作用域和活动对象被保存的现象
无论通过何种手段将内部函数传递到所在的词法作用域以外,它都会持有对原始定义作用域的引用
es6中模块文件中的内容会被当作好像包含在作用域闭包中一样来处理
关于this
- this是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调用时的各种条件
this全面解析
绑定规则
- 默认绑定,隐式绑定,显式绑定和new绑定
优先级
- new绑定 => 显示绑定 => 隐式绑定 => 默认绑定
bind函数
- 用于改变作用域和传入预定参数(柯里化的一种)
对象
浅拷贝
Object.assign(目标对象,源对象..)
属性描述符
writable // 是否可写
enumerable // 是否可枚举
configurable // 是否可配置
Object.preventExtensions() // 不能增加&&不能修改
Object.seal() // 不能增加&&不能修改&&不能配置&&不能删除
Object.freeze() // 不能增加&&不能修改&&不能配置&&不能删除&&不能访问&&不能遍历
ps:特性值操作只会影响对象的直接属性,不会影响其引用对象的属性
访问描述符
- 当使用getter和setter时,会忽略对象的value和writable特性
存在性
-
判断对象中是否存在对应的属性
````
'key' in obj // 方法一Object.prototype.hasOwnProperty.call(对象,属性名) // 方法二
````
遍历
-
对象
- for..in——进行对象遍历的时候,因游览器差异,顺序是不可靠的
-
数组
- for..of——通过调用迭代器对象,然后调用迭代器对象的next()方法进行遍历
// 数组有内置的@@iterator ,因此for..of可以直接应用在数组上 // 数组的迭代器对象通过"arr[Symbol.iterator]()"进行获取 // 对象进行for..of操作的变通方法 for (var key of Object.keys(someObject)) { console.log(someObject[key]); }
混合对象"类"
类意味着复制
传统的类被实例化时,它的行为会被复制到实例中;类被继承时,行为也会被复制到子类中
- 多态——在继承链的不同层次名称相同但是功能不同的函数
- 看起来似乎是从子类引用父类,但是本质上引用的其实是复制的结果
JavaScript也有类似的语法,但是和其他语言中的类完全不同;JavaScript 并不会(像类那样)自动创建对象的副本
混入模式(显式/隐式)可以用来模拟类的复制行为,但是通常会产生丑陋并且脆弱的语法,比如显式伪多态
(OtherObj.methodName.call(this,...))
,这会让代码更加难懂并且难以维护
原型
Prototype
如果原型链父级的属性被设置为只读,则实例对象无法创建屏蔽属性 (通过Object.defineProperty()可以)
如果原型链父级的属性被设为setter属性,则实例对象的赋值和更改操作都会自动延用原型链上的setter属性,体现为
实例属性本身的赋值或更改无效,除非setter属性方法下存在赋值操作 (通过Object.defineProperty()可以)
原型继承
真正的类继承是会进行对象复制的,但是javascript的继承本质是原型委托,通过原型来进行对象的关联
Object.setPrototypeOf(对象,被继承的原型)
行为委托
对象关联·行为委托
行为委托认为对象之间是兄弟关系,互相委托,而不是父类和子类的关系
通过在两个对象之间使用Object.create(对象)来实现行为委托,这种模式只需要两个实体,而且可以互为关联
只需要集中在对象之间的关联关系,可以更好地支持关注分离原则,创建和初始化并不需要合并为一个步骤(相比new 函数)
-
除了能让代码看起来更简洁,更具扩展性外,还可以简化代码结构
var Foo = { /* .. */ }; // 父类 var Bar = Object.create( Foo ); // 继承父类 Bar.fn=fnA; // 书写子类 var b1 = Object.create( Bar ); // 获取子类实例
内省检测·检查“类”关系
- 方法1 =>
A.isPrototypeOf(b)
- 方法2 =>
Object.getPrototypeOf(a)===A.prototype
- 方法3 =>
a.__proto__=== A.prototype
- 方法4 =>
a instansof A
《你不知道的javascript(上)》笔记的更多相关文章
-
你不知道的JavaScript上卷笔记
你不知道的JavaScript上卷笔记 前言 You don't know JavaScript是github上一个系列文章 初看到这一标题的时候,感觉怎么老外也搞标题党,用这种冲突性比较强的题目 ...
-
读书笔记-你不知道的JavaScript(上)
本文首发在我的个人博客:http://muyunyun.cn/ <你不知道的JavaScript>系列丛书给出了很多颠覆以往对JavaScript认知的点, 读完上卷,受益匪浅,于是对其精 ...
-
你不知道的javascript读书笔记3
概述 这是我看<你不知道的JavaScript(中卷)>中关于类型检查的笔记,供以后开发时参考,相信对其他人也有用. typeof 我们知道js中有七种内置类型:undefined, nu ...
-
《你不知道的JavaScript》笔记(一)
用了一个星期把<你不知道的JavaScript>看完了,但是留下了很多疑惑,于是又带着这些疑惑回头看JavaScript的内容,略有所获. 第二遍阅读这本书,希望自己能够有更为深刻的理解. ...
-
【你不知道的javaScript 上卷 笔记3】javaScript中的声明提升表现
console.log( a ); var a = 2; 执行输出undefined a = 2; var a; console.log( a ); 执行输出2 说明:javaScript 运行时在编 ...
-
<;你不知道的JavaScript>;读书笔记
近几天看了一本不错的 JavaScript 的书,是 Kyle Simpson 写的 <You Don't know JS>.这本书是 Kyle Simpson 在 Github 上的开源 ...
-
【你不知道的javaScript 上卷 笔记7】javaScript中对象的[[Prototype]]机制
[[Prototype]]机制 [[Prototype]]是对象内部的隐试属性,指向一个内部的链接,这个链接的作用是:如果在对象上没有找到需要的属性或者方法引用,引擎就 会继续在 [[Prototyp ...
-
【你不知道的javaScript 上卷 笔记6】javaScript中的对象相关内容
一.创建一个对象的语法 var myObj = { key: value // ... };//字面量 var myObj = new Object(); //new myObj.key = valu ...
-
【你不知道的javaScript 上卷 笔记5】javaScript中的this词法
function foo() { console.log( a ); } function bar() { var a = 3; foo(); } var a = 2; bar(); 上面这段代码为什 ...
随机推荐
-
字符串相似度算法(编辑距离算法 Levenshtein Distance)(转)
在搞验证码识别的时候需要比较字符代码的相似度用到“编辑距离算法”,关于原理和C#实现做个记录. 据百度百科介绍: 编辑距离,又称Levenshtein距离(也叫做Edit Distance),是指两个 ...
-
一个Java程序员应该掌握的10项技能
1.语法:必须比较熟悉,在写代码的时候IDE的编辑器对某一行报错应该能够根据报错信息知道是什么样的语法错误并且知道任何修正. 2.命令:必须熟悉JDK带的一些常用命令及其常用选项,命令至少需要熟悉:a ...
-
详解HTML<;head>; 头标签元素的意义以及使用场景
HTML<head>头部分的标签.元素有很多,涉及到浏览器对网页的渲染,SEO 等等,而各个浏览器内核以及各个国内浏览器厂商都有些自己的标签元素,这就造成了很多差异性.移动互联网时代,he ...
-
拥有iframe页面的子父类窗口调用JS的方法,并且注意的事项
一.前言 我页面用的是EasyUI的弹出窗口里面嵌入一个iframe.第一:父窗口打开子窗口是一个新增用户信息的iframe子页面,点击保存后,子窗口iframe则去调用父窗口的function cl ...
-
Oracle 11g RAC OCR 与 db_unique_name 配置关系 说明
一. 问题一 在做RAC standby 的alert log里发现如下错误: SUCCESS: diskgroup DATA was mounted ERROR: failed toestablis ...
-
java基础 第七章课后习题
1.改正后的应该为: String [] scores= new String[5]; 或者 String [] scores={ “ Mike”,"Lily" ," ...
-
linux sudo 运行找不到java、python命令
在Ubuntu环境中安装好Java环境后设置环境变量:在/etc/profile中设置好了JAVA_HOME变量并引入到PATH中, 由于Ubuntu默认是不以root用户登录的,这时echo $PA ...
-
torch.nn.Embedding
自然语言中的常用的构建词向量方法,将id化后的语料库,映射到低维稠密的向量空间中,pytorch 中的使用如下: import torch import torch.utils.data as Dat ...
-
【GIS】Vue、Leaflet、highlightmarker、bouncemarker
感谢: https://github.com/brandonxiang/leaflet.marker.highlight https://github.com/maximeh/leaflet.boun ...
-
侧滑返回导航栏以及TabBar隐藏和显示带来的坑
用系统的UINavigationBar时,返回手势重若碰到前一个页面有bar,后一个页面没bar,或者反过来时动画非常难看 如下图:因为首页隐藏了导航栏,在侧滑的时候导航栏竟然提前消失了,这是因为在侧 ...