作用域:
刚开始接触作用域与执行上下文栈(也叫全局词法环境)的时候,很容易把二者弄混。
一个作用域,不管执行几次,都还是只有一个作用域。
一个上下文,触发几次就有几个上下文。
注意点:
1.作用域与java中的块级作用域不同,java中是{}包裹着的算作作用域,Js中function算作用域
2.有全局作用域和function作用域
3. 在找变量存在于哪个作用域时,会从当前作用域开始,往上级逐级查找
4. 作用域可以隔离变量,形成闭包,使得在不同作用域下形成的相同名称的变量,不会冲突
5. 作用域在函数定义时就已经确定了,上下文环境在执行过程中产生
JS运行过程分为两个步骤:
1、预编译过程:执行上下文区域/全局词法环境
时间:执行代码之前完成
所做的事情:1)把所有var方式定义的变量全部存入上下文,赋值为undefine
2)把所有函数声明方式定义的函数名和函数体存入上下文
3)this运行时确定(预编译确定)
覆盖问题:
1)声明函数方式覆盖:后面的会覆盖前面的
2)后面的函数如果是表达式方式定义的,和属性var方式定义是一样的性质,会忽略
2、执行过程
时间:预编译完毕后的操作
所做的事情:1)把所有变量附上值
2)声明方式定义的函数不会再管了,只会处理表达式方式定义的函数
执行上下文栈:
图1--上下文理解示意图1
1. 执行上下文栈查找变量与作用域相同,从当前开始,逐级查找
2. 在预处理时,会有变量覆盖现象。优先级最高的是函数声明
如果后声明的函数名和之前声明的函数名冲突,冲突函数后面的会覆盖前面的
如果后声明的函数名和定义的属性名冲突,冲突函数后面的会覆盖前面的
如果后定义的属性名和之前声明的函数名冲突,则会忽略属性定义
3. 执行到全局上下文的时候,a,b的赋值为undefine,this=window,进入f1上下文开始给两个变量赋值
4. 如果调用f2函数多次,上下文就会产生多次,a,b变量值会增加并保存;再调用f1时,a,b会刷新归1
5. 所有的元素都是对象,包括function也是对象
6. 任何对象都有内部属性[[scope]]
7. 该内部属性包含了函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问
闭包:
使用时可以让函数作为返回值,即在function(){}中,加return function(){}.var一个变量接受function,再给变量传参即可。
例:
function a(){
var b=10;
return function c(m){
If(m>10){
console.log(b)
}
}
}
var x1=a();
x1(12);
条件:
1. 函数内部返回一个函数
2.返回的函数使用到了外部函数的自由变量
作用:
1.可以读取函数内部的变量,减少全局变量定义
2.减少函数传递参数的数量
3.让函数内部变量的值始终保持在内存中,不会在函数调用完毕后被自动清除
使用注意:
闭包使用父函数变量时候,只是个引用,而不是复制
父函数每调用一次,会产生不同的闭包
闭包中循环的问题
闭包的自执行格式写法
自执行写法:把函数用()包起来,强转形成表达式,末尾加(变量)
(function……)(i);
例:
(function(m){
var b=10;
m(20);
})(30);
自定义对象:
自定义对象:
Object:new方式创建对象构造函数传参:传的是对象,返回的依然是当前传入的参数
传的是基本类型,返回的是包装类型
Object自带函数:create 提供创建对象的方式
hasOwnProperty、keys
defineProperty/defineProperties
value/writable/enumerable/configurable/get/set
Get/set方法设置:
1)直接构造函数中给私有属性提供get和set
2)JSON格式提供get和set方法
3)Object类的属性定义方法来进行设置和绑定
注意:如果给属性定义了get/set,则这个属性就不能设置value和writable
构造器
定义:构造当前对象的函数,原型对象都应该有个构造函数属性,获取当前构造函数
注意:函数本身也是个对象
Function函数是所有对象的最终构造器
Object:所有对象的顶级对象
原型:
1、所有的函数都是对象
2、所有的函数可以独立封装属性
3、每个函数对象,本身自带了一个命名空间属性:prototype
4、prototype指向的是一个新的对象:原型对象
5、原型对象内部封装了一个属性,constructor
6、constructor指向当前构造函数本身
7、Prototype原型对象,在构造器和构造实例之间起了桥接作用
8、