01-延迟和异步加载JS
如何延迟加载JS:defer
defer:js脚本可以延迟到文档完全被解析后执行
<script type="text/javascript" defer src="路径"></script>
如何异步加载JS:async
** async :立即执行脚本,但不妨碍其他页面的操作,谁先加载完了谁执行**
<script type="text/javascript" async src="路径"></script>
02-变量的存储机制原理
变量的存储机制原理
数据类型分为:基本类型 和引用类型
1、内存
2、内存的声明周期(三个周期)
分配期:分配所需要的内存
使用期:读、写
释放期:不需要的时候将其释放
内存分配==》内存使用==》内存释放
3、javascript内存的生命周期
内存分配:分配你所需要的暂时使用的内存大小
内存使用:读、写内存
内存回收:对于不需要使用的内存将其释放
var num = 10; //内存分配
alert (num); //内存使用
num = null; // 内存回收
4、栈内存、堆内存
栈内存:
1、基本类型(string 、number 、boolean 、undefined 、null)
2、按值访问
3、存储的值大小固定
4、系统会自动分配内存空间
5、空间小,运行效率高
6、先进后出
堆内存:
1、引用类型(Object)
2、按引用访问
3、存储大小不固定
4、由代码进行制定分配
5、空间大,运行效率相对较低
6、无序存储(根据引用直接获取)
03-JS单线程
一、 JS语言是一个单线程:同一时间只能做一件事情,也就意味着所有的任务需要排队,前一个任务执行完成了,才可以继续执行下一个任务
二、JS语言为什么是单线程,取决于JS用在什么地方,与用户相关。
事件队列(定时器,ajax):先进先出
** 前端最重要的是:用户体验**
for(i=0;i<5;i++){
setTimeout(function(){
console.log(i);
},1000)
}
//输出 5个5
for(var i =0;i<3;i++){
setTimeout(function(){
console.log(i);
},1000*1)
}
//执行三次 每间隔1秒输出3
04-作用域和作用域链
一、作用域(作用的区域或者作用的范围)
全局作用域,全局就是window
二、作用域链:从内部向外,链(从当前作用域开始找,如果找不到向外作用域找,当找到就返回)
05-悬挂变量声明【变量提升】
js会提升所有变量声明,将它们移到作用域的开头
function fun(){
//var str;//变量提升
console.log(str);//undefined
var str = '123'
console.log(str);//123
}
06- 优先级--作用域面试题
1、作用域链:从内部(当前作用域)逐级向上查找
2、顺序、优先级
变量 > 函数 > 参数 > 变量提升
07-严格模式
一、严格模式:use strict
二、使用方式
- 1、针对于整个文件【全局】,文件开头第一行写入use strict
- 2、针对于单个函数【局部】,函数内开头第一行写入use strict
<script type="text/javascript">
'use strict' // 全局方式
</script>
function fun1(){
'ust strict' //严格模式局部
}
function fun(){
//不是严格模式
}
三、作用
1、变量声明问题:var |window
str = 123;//报错
2、禁止this关键字指向全局对象
3、参数重名问题,函数不能有重名的参数
4、arguments对象不能赋值
function fun4(){
arguments.length = 20;
console.log(arguments.length,arguments[19]);
}
fun4();
//正常可以运行
function fun4(){
'use strict'
arguments= 20;
console.log(arguments.length);
}
fun4();
//严格模式会报错,arguments.length 还未修正 不能修改arguments
08-闭包
一、块级作用域
{} js没有块级作用域
function(){
js中函数有作用域
}
二、作用域和作用域链
- 原理:当函数声明的时候,函数会通过内部属性,scope来创建范围
三、 闭包
1、什么是闭包:闭包是一个函数加上到创建函数的作用域的连接,闭包就是关闭了函数的自由变量
简单理解:
- 第一句话(得到信息):有2个函数,作用域是连接关系。【scope】
- 第二句话(得到信息):变量不自由==》会停留在内存中,不会销毁
function fun( n ){ //关闭了n的自由 n会保存在内存中
return function(m){
n+=m;//同n = n+m;
return n;
}
}
var f = fun(5)
f(1);//n =6
f(1);//n =7
f(1);//n =8 n会保存在内存中
2、闭包可以做什么事儿?无意间共享环境
var lis = document.getElementByTagName('li')
for(var i=0 ;i<lis.length;i++){
(function(){
var idx = i;
lis[i].onclick = function(){
console.log(idx);
}
})()
}
09-undefined和null区别 instanceof
一、 回顾数据类型
- 原始数据类型(基本数据类型)
- 字符串string('132')、数值number(1,2,3)、布尔boolean(true,false)、undefined(未定义)、null(没有对象)
- 引用类型
- 对象:Object
基本数据类型和引用数据类型的区别:
每个对象都有唯一的标识,并且(严格地)等于自身
undefined和null区别
作者先设计的null,后设计的undefined
JavaScript的最初版本是这样区分的:null是表示一个“无”的对象(空指针),转换为数值时为0;undefined是表示一个“无”的原始值,转为数值时为NaN
注意null的问题:typeof null 返回‘Object’是一个无法修复的错误
二、检测类型
- typeof
- instanceOf :返回布尔类型
- 语法格式:检测的数据 instanceof 所属构造函数名称type instanceof Object
function fIsType(type){
if(type instanceof Array){
console.log("数组");
}else if(type instanceof Object){
console.log("对象");
}
}
fIsType([1,2,3])
fIsType(null)
fIsType({})
10-this指向
- this指向:this指的是函数运行时 所在的“环境”
补充:引擎会将函数单独保存在内存中
历史原因:js语言设计this,是跟内存的数据结构有关系。
原理:函数可以在不同的环境下运行执行,所以就需要一种机制,能够在函数体内获取当前函数的运行环境。
this的设计目的就是在函数体内,指向函数当前的运行环境
11-函数和对象的原型关系
函数:有 prototype
对象:有 proto
function Fun(){
this.name = '张三'
}
var obj = new Fun();
console.log(obj.name);//张三
console.log( Fun.prototype === obj.__proto__ );//true
//Fun是一个函数
//obj是一个对象
构造函数的Fun.prototype和对象的obj.proto指向同一个原型对象
12-浅拷贝和深拷贝
什么是拷贝
浅拷贝:只复制一层对象,当对象的属性是引用类型时,实质上是复制的其引用,当引用指向的值发生变化的时候,原对象的属性值也会跟着发生变化,互相影响 Object.assign();
深拷贝:在拷贝的时候,创建新的对象,并且把原对象所有的属性都深拷贝到新对象,原属性如果是对象,也会重新创建新的对象并且拷贝到新对象的属性中,这样旧对象和新对象就是互相独立的,互不影响。
- 1、JSON.parse() + JSON.stringify()
var o ={
a:1,
b:{
a:'你好'
}
}
var m = JSON.parse(JSON.stringify(o))
console.log(o,m);
m.b.a = '不好'
console.log(o,m);
- 2、
//封装一个深拷贝方法
var obj = {
a: 1,
b: {
a: "你好",
},
};
function fun(obj) {
var m = {};
if (typeof obj === "object") {
for (var k in obj) {
if (obj.hasOwnProperty(k)) {
if (typeof obj[k] == "object") {
m[k] = fun(obj[k]);
} else {
m[k] = obj[k];
}
}
}
}
return m;
}
var createObj = fun(obj);
console.log(createObj.b.a);
console.log(obj.b.a);
createObj.b.a = "不好";
console.log(createObj.b.a);
console.log(obj.b.a);