- 先编译再运行,编译的时候会在作用域中添加变量,运行的时候才给变量赋值
所以js的作用域是静态的,定义在哪里就取哪里的作用域
js对编译做了很多优化,如果使用with和eval,编译速度会变慢
- 作用域
全局作用域 函数作用域 catch作用域
let const 会设置一个作用域 最外层是Script, 包裹{}是Bolck
- 函数声明和函数表达式
函数声明:function fn() {} // 函数声明比变量优先
函数表达式: var fn = function f() {} // f只能函数内部访问到
- 闭包
函数具有将当前作用域保存到closure作用域当中的能力 当外部作用域调用这个函数的时候,closure会保存不会销毁 回调函数都是闭包
- this
调用位置定义:当一个函数被调用的时候,会创建一个活动记录(执行上下文)。这个记录会包含函数的调用栈,函数的调用方式、传入的参数等信息。
调用位置有上下文对象,this指向上下文对象
全局定义的函数调用的时候,this指向global 严格模式this是undefined
obj.fn this指向obj;
f1 = obj.fn
f1()// 调用栈global -> f1 非严格模式 this指向global
bind(this)返回的是一个函数,可以用来柯里化;call和apply都是直接调用
箭头函数this指向作用域中的this
嵌套函数不会继承this
const obj = {
a: 1,
f1: function() {
console.log(this.a) // 1
function f2 () {
console.log(this.a) // undefined 调用位置没有上下文对象,指向全局或者undefined
}
}
}
obj.f1()
function func() {
this.name = 'aaa'
this.person = {
name: 'bbb',
getName: () => {// 箭头函数从定义时的函数继承上下文
debugger
console.log(this.name)
},
getInnerName: function () {// this指向调用的时候的当前上下文person
debugger
console.log(this.name)
}
}
}
let f1 = new func()
f1.person.getName() // aaa
f1.person.getInnerName()// bbb