JS(数据类型、预解析、闭包、作用域、this)
1、数据类型的区别
基本数据类型:number、string、boolean、null、undefined
引用数据类型:
1-1:对象数据类型:Object、Array、Date、Regexp、String、Boolean等
1-2:函数数据类型function
2、预解析(变量提升)
在当前作用域中、JS从上到下执行、首先把带var和function关键字的进行声明和定义
2-1:声明(declare):var num = 12; 在预解释状态为 var num = undefined;
2-2:定义(defined):赋值
2-3:var:在预解析的时候只提前声明、在代码执行过程中才定义赋值
2-4:function:预解析的时候完成了声明 + 定义(函数内的代码 --- 按照"字符串"存储在新开辟的堆内存中)
2-5:堆内存:引用数据类型新开辟的地址所在的空间(存储引用数据类型的值)
2-6:栈内存:存储基本数据类型的值、提供JS代码执行环境\
3、作用域("闭包")
函数执行的时候会形成一个新的私有作用域(给形参赋值 --- 预解析(变量提升) ---代码执行)
新的私有作用域、保护里面的私有变量不受外界干扰、这种函数的保护机制 --- "闭包"
3-1:私有变量:在私有作用域中声明的变量都为私有变量(受作用域保护)、形参也是私有变量(执行在预解析之前)
3-2:变量查找:在私有作用域中出现了变量
3-2-1:首先查找是否为私有变量(是否在私有作用域中定义)
3-2-2:若不是私有变量、则向上级作用域查找
3-2-3:若上级作用域中没有、则继续向上查找、知道window为止
3-3:查找上级作用域:上级作用域的位置、和函数在哪里执行没有关系、和当前函数对象的堆内存在哪里定义有关系
(在那定义、当前函数的上级作用域就是谁)
4、不销毁作用域
函数执行、会形成一个私有作用域、在私有作用域中返回一个"引用数据类型"的值、在外面有变量接受。则当前这个作用域不能被销毁
1、函数执行、返回一个"引用数据类型"的值、但是在外面没有变量接受、那么当前的这个作用域处于"不立即销毁"、当Browser空闲的时候自动销毁
2、一般情况下、函数执行完成会自动销毁(GC)
3、作用域不销毁的第二种情况(赋值给一个DOM元素、的事件)
oDiv.onclick = (function(){
return function(){
oDiv.innerHTML = 0;
}
})();
前提条件、在一个作用域当中的返回值、return
5、this
一般值函数中的this
this是誰和"函数"在(那里定义)和(在那里执行)没有关系
1、自执行函数的this永远是window
2、给元素绑定方法,当触发事件并执行对应方法的时候、方法中的this是当前元素
3、不管函数在那里执行、我们只需要查看函数名之前是否有"."、有的话、"."前面的是誰this就是誰
预解析的N种情况:
1、不管判断条件是否成立、都会进行预解析
2、只对"="左边的进行预解析、右边的是值、不进行解析
3、自执行函数不进行预解析
4、函数体中的return后面的返回值(function)不进行预解析、但其后面的代码需要预计西
5、预解析支队同一个脚本快起作用
6、如果预解析的时候发现了重名(不重新声明、但是需要重新定义)
在什么情况下函数function不进行预解析
1、自执行函数 (function(){})();
2、等号右边的函数 oDiv.onclick = function(){}
3、return 后面的函数 return function(){}
将其他数据类型转换为Boolean类型规则( 0、NaN、""、Null、undefined 转换为false)其他均为true
在全局作用域中var num = 12 和 num = 12的区别
1、带var的在代码执行之前进行预解析、没var的不可以
2、num = 12的意思是给window增加一个名叫num的属性名、赋值属性为12 --- window.num = 12;
3、var num = 12; 在全局作用域下、也同样相当于给window定义了一个叫做num的属性名、属性值为12
小练习
[] == []; ![] == []; [] == false; ![] == false; console.log("a" in window); fn(); function fn(){console.log(1);} var fn; fn(); function fn(){console.log(2);} fn(); var fn = 13; function fn(){console.log(3);} fn(); var num = 2; var obj = { num: 4, fn: (function () { this.num *= 2; num *= 2; var num = 3; return function () { this.num *= 2; num *= 3; console.log(num); } })(), db1: function () { this.num *= 2; } }; var fn = obj.fn; console.log(num); fn(); obj.fn(); console.log(num); console.log(obj.num);
居敬持志~ Coding