作用域和闭包
作用域分为:全局作用域、函数作用域、块级作用域(ES6新增)
//ES6 块级作用域
if (true) {
let a = 100;
}
console.log(a) //会报错
闭包
作用域应用的特殊情况,有两种:
函数作为参数被传递
函数作为返回值被返回
//函数作为返回值
function create() {
const a = 100;
return function() {
console.log(a)
}
}
const fn = create()
const a = 200
fn () //100
//函数作为参数被传递
function print(fn) {
let a = 200;
fn()
}
let a = 100
function fn() {
console.log(a)
}
print(fn) //100
//所有地方自由变量的查找,是在函数定义的地方,向上级作用域查找
// 不是在执行的地方!!!
this
作为普通函数调用、使用call apply bind调用、作为对象方法被调用、在class方法中调用、箭头函数中调用,this在个个应用场景中取什么样的值,是在函数执行确认的不是函数定义的时候确认的
function fn1() {
console.log(this)
}
fn1() //window
fn1.call({x:100}) //{x:100}
const fn2 = fn1.bind({x:200}) //bind会返回一个新的函数去执行
fn2() // {x:200}
const zhangsan = {
name: '张三',
sayHi() {
//this 指向当前对象
console.log(this)
},
wait() {
setTimeout(function(){
//this === window
console.log(this)
})
},
waitAgain() {
setTimeout(()=>{
//this 指向当前对象
console.log(this)
})
},
}
class People {
constructor(name) {
this.name = name
this.age = 20
}
sayHi() {
console.log(this) //指向当前的实例
}
}
const zhangsan = new People('张三')
zhangsan.sayHi() //zhangsan对象
手写bind函数
Function.prototype.bind1 = function () {
//将参数解析为数组
const args = Array.prototyoe.slice.call(arguments)
//获取 this (取出数组第一项,数组剩余的就是传递的参数)
const t = args.shift()
const self = this //当前函数
//返回一个函数
return function () {
//执行原函数,并返回结果
return self.apply(t,args)
}
}
function fn1(a,b,c) {
console.log('this',this)
console.log(a,b,c)
return 'this is fn1'
}
const fn2 = fn1.bind1({x:100},10,20,30)
const res = fn2()
console.log(res)