天天看点

你不知道的javascript(上卷)-(中卷)

作用域

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, 只要使用了回调函数,实际上就是使用闭包

经典循环闭包问题

  1. 因为没有在IIFE中写入任何内容,相当于是一个空壳,所以结果还是 6;
for(var i = 1; i<= 5; i++) {
	(function() {
		setTimeout(function() {
			console.log(i);
		}, i*1000)	
    })()
}
           
  1. 在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) ;
	}
}
           

中卷

强制类型转换

  1. 守护运算符
function fn() {
	console.log(a);
}
a && fn()
//  fn在条件判断通过时才会执行
           

ES6中出现的

symbol

类型不能够被隐式类型转换

var s2= Sumbol("not cool");
s2 + ""  // TypeError
           
  1. 抽象关系比较

    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

继续阅读