1、 this 是什么:
任何函数本质上都是通过某个对象来调用的,如果没有直接指定 就是window
所有函数内部都有一个变量this,它的值是调用当前对象
2、如何确定this的值
test() 是一个函数
test(): this是window
p.test(): this是p
。。。=new test() :this是新创建的对象
p.call(obj) :this 就是obj
call 和apply 都是对函数进行调用,这两个方法的第一个参数都是函数本身,
不同的apply传入的是参数数组,即先定义一个数组包含函数的参数集合,,而call则可以直接写参数
3、prototype:原型对象,可以动态的向对象添加对象或方法 每个函数对象都有一个prototype属性,指向空的object对象
原型对象有一个属性constructor,指向函数对象
4、每个函数function都有一个显示原型prototype 隐式原型 _proto_ 对象的隐式原型的值是其对应的显示原型的对象的值
5、instanceof 判断左边的对象是不是右边的实例 fun instanceof function 或者 fun instanceof object A instanceof B
判断标准:如果B函数的显示原型对象在A对象的原型链上 返回true
6、变量提升 作用域
变量声明提升:通过VAR 声明的变量,在定义语句之前可以访问到,值是undefined
函数声明提升:通过function声明的函数,在函数调用之前可以直接调用,值是函数定义(对象)
this ==》赋值(window)
作用域和作用域链:作用域其实就是定义函数的那一块,分为全局作用域和局部作用域。为了提高代码的可观性,也可以避免名字冲突性 作用域共有n+1个,n就是定义的函数个数,1就是全局作用域
作用域链决定了哪些数据能够被函数访问,同样的执行上下文页游n+1个,n是函数执行的次数,1同样是全局的执行上下文
作用域和执行上下文(EC 执行环境 execution context): 每个执行上下文中都有它自己的变量对象 VO(Variable object)
作用域在函数创建的时候就产生了 而执行上下文是在函数调用的时候产生的 。执行上下文 就是在函数执行的时候创建一片区域,用于存储执行上下文中的变量 、函数声明 、函数参数,调用一个创建一个(为函数分配一片区域),当函数执行完之后,会释放其空间,以供反复使用。 函数的执行上下文 函数内部可见 外部不可见
在执行全局上下文之前,js引擎会创建一个栈来存储管理所有执行上下文对象。当全局执行上下文创建后 添加到栈中(压栈) 函数执行上下文 创建后 添加到栈中(压栈) 执行完之后 出栈 最后栈中只剩下 window
全局执行上下文:1、在执行全局代码前将window确定为全局执行上下文 2、对全局数据进行预处理 a:var定义的全局变量为undefined ,添加文window的属性 b:function声明的全局函数赋值(fun)定义为window的 方法 c:this 赋值(window)3、开始执行全局代码
函数执行上下文:1、在调用函数,准备执行函数体之前,创建函数上下文对象 2、对局部数据进行处理 a、形参变量(赋值)---》实参 添加为局部上下文的属性 b、arguments 赋值实参列表 添加为执行上下文的属性 c、 var定义的局部变量 undefined 添加为执行上下文的属性 d、function 声明的函数 赋值(fun) 添加文执行上下文的方法 e、this 赋值 window
3、开始执行函数体代码
但是如果通过new方式(初始化)的方式----->不能访问到 var =new function(){}
var a=3
function f(){
console.log(a);
var a=4
}
f()------>输出为Undefined
以上等价于
function f(){
var a;----->undefined 在输出之后赋值,不会输出
console.log(a);
a=4
}
7、闭包 当一个内部函数调用嵌套的外部函数的变量时,就产生了闭包(条件:1、函数嵌套 2、内部函数引用外部函数的变量 3、执行外部函数)
闭包的作用:使用函数内部的函数访问外部函数的变量之后,仍然存活在内存中,延长了局部变量的生命周期 让函数外部可以访问(操作)到函数内部的数据(变量)
闭包的缺点:函数执行完之后,函数的局部变量没有释放,占用内存时间会变长 容易造成内存泄漏
闭包的应用:定义特定的js模块 具有特定功能的JS文件 将所有的数据和功能封装在一个函数内部 只向外暴露一个包含n个方法的对象和函数 模块的使用者,只需要调用模块就能调用并实现相应的功能
闭包有没有产生 就看内部函数有没有被创建
8、内存溢出 :当程序运行需要的内存超出了浏览器 剩余的内存是 就会抛出内存溢出的错误
内存泄漏:占用的内存没有释放 常见的内存泄漏:意外的全局变量 没有及时清理的计时器或回调函数 闭包
9、对象字面量:使用大括号{}创建对象(键值对),同时制定属性、方法等
工厂模式:当需要创建多个对象,而这些对象又可能会UI有大部分的重复时,使用工厂模式 其实就是讲对象放在一个函数中,这样创建多个对象时,只需要给定不同的参数就可以了
function fun(name,age){
var obj={
name:name,
age:age,
showname:function(name){
this.name=name
}
}
return obj;
}
但是多个对象都是同样的类型 object类型 ,那么就需要另一种方式将其分开来,到底是哪种类型 此时就不需要创建对象了,也不需要返回object
function fun(name,age){
this.name=name,
this.age=age,
showname:function(name){
this.name=name
}
}
但是这样每个数据都有相同的数据 即 showname 每次创建一个新的对象时,都会创建一个showname 此时可以经此方法放在最外面 但是 会污染全局变量 ,使用原型对象 ,
就不会污染全局变量了
构造函数 :详见vs2015 编译器 htmlpage1
子类型的原型指向父类型的实例
child.prototype=new parent
child.prototype.constructor=child
多进程:一个应用程序同时启动多个实例运行
多线程:在一个进程内,同时有多个线程运行
多线程:提高CPU的利用率 缺点:创建多线程 开销 线程之间切换开销 死锁与状态同步问题
单线程:顺序变成简单易懂 缺点:效率低
js是单线程运行的 但是使用 web workers 可以多线程运行
原因:作为浏览器脚本语言,javascript的主要作用就是与用户互动,以及操作DOM,这决定了它只能是单线程的,否则会带来很麻烦的同步问题
浏览器是多线程运行的 有 单进程运行的,页游多进程运行的
alert的作用就是暂停当前主线程(注意 是主线程)的执行,同时暂停计时 当设置了定时器之后 会重启定时器的运行
定时器不一定是定时的
settimeout的回调函数是在主线程中执行的
定时器回调函数只有在运行栈中的代码全部执行完之后,才开始执行
js执行代码流程:
先执行初始化代码 也就是一些基本的代码
有定时器设置定时器
绑定监听
发送ajax请求
在后面某个时刻执行回调代码
内存的结构:线程执行时在内存形成的空间为栈,进程形成堆结构
回调函数 :就是将一个函数当作参数传给另一个函数,被传的函数叫做回调函数,主要的用意就是当主函数完成后再去执行回调函数
回调函数分为:dom事件回调函数(获取标签,如按钮,给其添加onclick事件) 定时器回调函数 ajax请求回调函数 生命周期回调函数 特点:自己定义的 没有调用 但是执行了
斐波那契数列 f(n)=f(n-1)+f(n-2)
function(n){
return f(n-1)+f(n-2)
}
alert是window的对象 ,分线程中不能使用
事件处理机制:代码分类:初始化执行代码:包括绑定dom事件监听,设置定时器没法送ajax请求的代码
回调执行代码:处理回调逻辑
js引擎执行代码的流程:初始化代码====》回调代码
模型的两个重要组成部分:事件管理模块 和 回调队列
模型的运转流程 :执行初始化代码,将事件回调函数交给对应模块管理
当事件发生时,管理模块会将回调函数及其添加到回调队列中
只有初始化代码执行完成之后,才会遍历读取回调队列中的回调函数执行
浏览器内核:是支持浏览器运行最核心的模块
不同的浏览器的内核可能不一样 谷歌。safari:webkit ie:trident
内核由很多模块组成{
js引擎:负责js程序的编译和运行
html css:负责页面文本的解析
dom/CSS:负责dom/css在内存中的相关处理
布局和渲染模块:负责页面的布局和效果的绘制
定时器模块:负责定时器的管理
事件响应模块:负责事件的管理
网络请求模块:负责ajax的处理