变量声明提升:
通过var定义的变量,在定义之前就可以访问到,不过值为undefined
函数声明提升:
函数在未声明以前就可以提前调用。
全局执行上下文。
var定义的全局变量=undefined,添加为window属性
function声明的全局函数= 赋值fun。添加为window的方法
this=赋值(window)
函数执行上下文
在调用函数时,执行函数体之前,创建对应的函数执行上下文对象(虚拟的,存在于栈中)
对局部的数据进行预处理
形参---》添加实参属性,添加为上下文的属性
argument ---》赋值(实参列表),添加为执行上下文的属性。
作用域与作用域链
函数n+1个作用域
闭包:
<script type="text/javascript">
var btns = document.getElementsByTagName("button");
/*
for(var i = 0,length=btns.length;i<length;i++){
var btn = btns[i]
btn.index = i
btn.onclick = function(){
alert("第"+(this.index+1)+"个");
}
}*/
for(var i = 0,length=btns.length;i<length;i++ ){
(function(i){//匿名函数自调用---》闭包
var btn = btns[i]
btn.onclick = function(){
alert("第"+(i+1)+"个");
}
})(i)
}
</script>
如何产生闭包:
当一个嵌套的内部子函数引用了嵌套的外部父函数的变量(函数)时,就产生了闭包
函数嵌套,内部函数执行外部函数。
执行函数定义就会产生闭包,不需要调用内部函数
闭包:
- 嵌套的内部函数
- 包含被引用变量的对象
作用:
- 使函数的内部变量在函数执行完以后,任然存活在内存中(延长了局部变量的生命周期)
- 使函数外部可以读取操作内部函数的数据(变量/函数)
闭包的生命周期
在嵌套的内部函数定义执行时候就产生了。
在嵌套的内部函数成为垃圾对象时结束。
自定义JS模块
具有特定功能的JS文件
将所有的数据和功能封装在一个函数内部(私有的)
只向外部暴露一个或n个方法的对象或者函数
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="js/myModel.js"></script>
<script type="text/javascript" src = "js/myModel01.js"></script>
<script type="text/javascript">
/*var model = myModel()
model.doSomthing()
model.doOtherThing()*/
myModel01.doSomthing()
myModel01.doOtherThing()
</script>
</head>
<body>
</body>
</html>
function myModel(){
var msg = 'my sy'
function doSomthing(){
console.log('ssd'+msg.toUpperCase())
}
function doOtherThing(){
console.log('SSD'+msg.toLowerCase())
}
//向外暴露给外部使用的方法
return {
doSomthing:doSomthing,
doOtherThing:doOtherThing
}
}
(function(window){//Demo压缩的,如果没定义
var msg = 'my sy'
function doSomthing(){
console.log('ssd'+msg.toUpperCase())
}
function doOtherThing(){
console.log('SSD'+msg.toLowerCase())
}
window.myModel01 = {
doSomthing:doSomthing,
doOtherThing:doOtherThing
}
})(window)
闭包缺点:
函数执行完以后,函数内的局部变量没有释放,占用内存时间会变长
容易内存泄漏
解决:尽量不用,及时释放
内存溢出与内存泄漏:
当程序运行需要的内存超出了剩余的内存时。就会出现内存溢出错误
意外的全局变量,闭包,未及时关闭的定时器或回调函数
对象创建模式:
var p = new Object();
var p = {
name:"d",
age:12
}
//构造函数和原型的组合模式
function Person(name,age){
this.name = name
this.age = age
}
Person.prototype.setName = function(name){
this.name = name
}
var p1 = new Person("1",2)
var p2 = new Person("2",3)
继承模式
原型链继承
子类型的原型为父类型的实例对象
借用构造函数继承。call
进程与线程
进程:程序的一个执行,具有独立的内存空间
线程:进程内的一个独立的执行单元,是程序执行的一个完成流程,cpu执行的最小单元
浏览器的内核
内核由很多模块组成。
主线程
JS引擎模块:负责Js程序的编译与运行
html,css文档解析:负责页面的文本解析
DOM/CSS模块:负责dom/css在内存中的相关处理
布局和渲染:页面的额布局和效果的绘制(内存中的对象)
分线程
定时器模块:定时器的管理
事件响应模块:事件的管理
网络请求模块:ajax请求
定时器
h5 web workers(多线程)
将大计算量的Demo交给web worker执行
子线程完全受主线程控制。
分线程中的全局对象不再是window,不可能更新界面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<input type="text" id="number" placeholder="数值" />
<button id="btn">计算</button>
<script type="text/javascript" src="js/work.js">
</script>
<script type="text/javascript">
var input = document.getElementById("number")
document.getElementById("btn").onclick = function(){
var number = input.value
var worker = new Worker("work.js")
//绑定接收消息的监听
worker.onmessage = function(event){
console.log("主线程接收分线程返回的数据"+event.data)
alert(event.data)
}
//发送消息
worker.postMessage(number)
console.log("主线程向分线程发送数据:"+number)
}
</script>
</body>
</html>
function fibonacci(n){
return n<=2 ? 1:fibonacci(n-1)+fibonacci(n-2);
}
var onmessage = function(event){
var number = event.data
console.log("分线程接收到主线程发送的数据:"+number)
var result = fibonacci(number)
postMessage(result)
console.log("分线程向主线程返回数据"+result)
}
来源:CSDN
作者:一李
链接:https://blog.csdn.net/qq_43641432/article/details/103534148