作用域规则
一、LHS查询
二、RHS查询
三、词法作用域
1、每一个函数都会创建一个新的作用域
2、作用域查找会在找到第一个匹配的标识符时停止
3、全局对象:由宿主平台决定,浏览器为windows对象。全局变量会自动称为全局对象的属性。
4、欺骗词法作用域会导致性能下降
5、eval 函数(不建议使用):把字符串内容,转成了代码。严格模式下,无法修改作用域
6、setTimeout 、setInterval,第一个参数时动态字符串代码,已经过时。
7、new Function(…) 的最后一个字符串,避免使用。
8、避免使用 with
9、函数会比变量先提升,所有同名的变量声明不起作用
10、函数表达式的赋值操作不会被提升
四、动态作用域(可忽略,JS不采用)
五、ES6 功能
1、let : 块作用域变量
2、const :块作用域常量
3、
六、XXX
异常 Error
一、Reference
二、Type
闭包
定义:相当于返回一个内部的函数。在自己定义的词法作用域以外的地方执行。使得函数可以继续访问定义时的词法作用域。
1、使用let 块作用域,简化闭包的写法
2、模块模式:1)必须有封闭的外部函数,并且被调用(每次调用创建新的模块) 2)至少返回一个内部函数
3、模块模式若时单例:采用IIFE方式即可
4、apply 函数
5、ES6功能:1)增加了一级语法支持,把文件当作独立的模块来处理,一个文件一个模块
2)采用 export 与 import … from 语法,关键字 module
6、XXX
this
1、从匿名对象引用自身:arguments.callee 但被弃用
2、this在任何情况下都不指向函数的词法作用域
3、this 的绑定与函数声明的位置没有任何关系,只取决于函数的调用方式
4、ES5提供的内置方法: Function.prototype.bind,可以去除赋值函数
5、new 绑定
1)创建一个全新的对象
2)新对象会被执行【原型】连接
3)这个新对象会绑定到函数调用的this
4)如果函数没有返回其他对象,那么会自动返回这个新对象。
6、this绑定的四条规则的优先级:
1. 函数是否在 new 中调用(new 绑定)?如果是的话 this 绑定的是新创建的对象。
var bar = new foo()
2. 函数是否通过 call、apply(显式绑定)或者硬绑定调用?如果是的话,this 绑定的是
指定的对象。
var bar = foo.call(obj2)
3. 函数是否在某个上下文对象中调用(隐式绑定)?如果是的话,this 绑定的是那个上
下文对象。
var bar = obj1.foo()
4. 如果都不是的话,使用默认绑定。如果在严格模式下,就绑定到 undefined,否则绑定到
全局对象。
var bar = foo()
5. 如果你把 null 或者 undefined 作为 this 的绑定对象传入 call、apply 或者 bind,这些值
在调用时会被忽略,实际应用的是默认绑定规则。
7、Function.prototype.bind():第一个参数绑定的是对象,其他参数可柯里化(预先设置一些参数)。
8、ES6中:可以用 … 代替 apply(null) 。 foo(…[2,3]) ; 相等于 foo.apply(null, [2,3])
9、创建一个空对象 :Object.create(null);
10、ES6中的 => 函数:不使用this的四种标准规则,而是根据外层或则全局作用域来决定this
用于回调函数中。 尽量避免使用 self=this 和箭头函数
11、XXX
对象
1、函数本质跟对象一样,只是可以调用。
2、数组也是一种对象,具备一些额外的行为。
3、ES6 增加了可计算属性名
4、函数是一等公民,永远不会属于某个对象,对象的方法只是对象的属性名指向一个函数。
5、一个巧妙的深复制方法(需要保证对象是JSON安全):var newObj = JSON.parse( JSON.stringify( someObj ) );
6、 ES6 定义了 Object.assign(…) 方法来实现浅复制
7、从 ES5 开始,所有的属性都具备了属性描述符。
8、即使属性是 configurable:false , writable 状态还是可以从true修改为false
9、不变性:禁止扩展(preventExtensions),密封(seal),冻结(freeze)
seal ,进一步设置现有属性标记为 configurable:false;
freeze,进一步设置属性标记为 writable:false。 即相当于所有的内容都是常量(模仿不可变类)
10、Getter 与 Setter 方法:
如果已经存在这个属性,[[Put]] 算法大致会检查下面这些内容。
- 属性是否是访问描述符(参见 3.3.9 节)?如果是并且存在 setter 就调用 setter。
- 属性的数据描述符中 writable 是否是 false ?如果是,在非严格模式下静默失败,在
严格模式下抛出 TypeError 异常。 - 如果都不是,将该值设置为属性的值。
- getter 是一个隐藏函数,会在获取属性值时调用。setter 也是一个隐藏
函数,会在设置属性值时调用。只能用于单个属性上面
11、ES6 增加了一种用来遍历数组的 for…of 循环语法
12、ES6 有 class 关键字
类
1、JS只有对象,类的概念是属于构造函数的。属于构造函数之间不存在直接的关系。
2、JS本身并不提供多重继承
3、JS在ES6之前没有相对多态的机制,可采用显示多态,应该避免使用。
[[Prototype]]
1、new 会劫持所有普通函数并用构造对象的形式来调用它。
2、Foo.prototype的 .constructor属性只是Foo函数在声明时的默认属性。
3、声明函数时,就会有一个.prototype属性关联到默认的对象,这个.prototype属性可以修改关联其他对象
4、ES6:Object.setPrototypeOf( Bar.prototype, Foo.prototype )
412



被折叠的 条评论
为什么被折叠?



