作用域
LHS & RHS 赋值操作的左右侧
赋值操作的目标(LHS)
谁是赋值的源头(RHS)
两种工作模型
词法作用域
只会查找一级标识符
欺骗词法作用域:
eval()
在严格模式下,会有自己的词法作用域,意味着其中的声明无法修改其所在的作用域;
with()
会创建一个单独的作用域,尽量不要使用
表面看 javascript没有块级作用域
使用 try … catch 语句 catch中为块级作用域
先有鸡还是先有蛋
先声明后赋值;[案例已懂]
作用域闭包
将内部函数传递到所在词法作用域之外,它会始终持有对原始定义作用域的引用,无论在何时执行这个函数都会使用闭包;
function a() {
var a = 3;
function b() {
console.log(a);
}
return b;
}
var c = a() ;
闭包应用广泛,随便举几个例子:
function wait(msg) {
setTimeout(function timer(){
console.log(msg);
},1000);
}
wait('wait for a second!');
函数 timer() 传递给 setTimeout,timer函数持有对wait() 作用域的闭包。同时保持对msg的引用;
还有 ajax请求,跨窗口通信,web Workers, 只要使用了回调函数,实际上就是使用闭包
经典循环闭包问题
- 因为没有在IIFE中写入任何内容,相当于是一个空壳,所以结果还是 6;
for(var i = 1; i<= 5; i++) {
(function() {
setTimeout(function() {
console.log(i);
}, i*1000)
})()
}
- 在IIFE中进行赋值,并通过参数进行传递
for(var i = 1; i<= 5; i++) {
(function(j) {
setTimeout(function() {
console.log(j);
}, j*1000)
})(i);
}
附录
词法作用域
正确使用和包含this机制
var obj = {
count: 0,
cool: function coolFn() {
if(this.count <1){
setTimeout(()=> {
console.log("cool");
},100);
}
}
}
var cool = "outside is not cool";
var obj = {
count: 0;
cool: function coolFn() {
setTimeout(function timer()
{
if(this.count<1){
console.log("cool");
}
}.bind(this),100) ;
}
}
中卷
强制类型转换
- 守护运算符
function fn() {
console.log(a);
}
a && fn()
// fn在条件判断通过时才会执行
ES6中出现的 symbol
类型不能够被隐式类型转换
var s2= Sumbol("not cool");
s2 + "" // TypeError
- 抽象关系比较
2.1 双方都是字符串,按照字母顺序来比较
2.2 为了保证安全,应该在关系比较中进行显示强制类型转化;
var a = { b : 2};
var b = { b : 3};
a > b //flase
a == b //false
a < b //false
a >= b // true a<=b 被处理为 !(a>b) 小于等于其实是不大于
a <= b //true
获得函数的表达值
es7 “do表达式”
do{…} 执行一个代码块,包含一个或多个语句,并且返回最后一个语句的结果值,然后赋值给变量a
运算符优先级
Javascript中的 && 和 || 运算符返回它们其中一个操作数的值,而非 true 或者 false