题目
- this的不同应用场景,如何取值
- 手写bind函数
- 实际开发中闭包的应用场景,举例说明
闭包
作用域应用的特色情况,有两种表现
- 函数作为参数被传递
- 函数作为返回值被返回
自由变量的查找,在函数定义的地方,向上级作用域查找不是在执行的地方
//函数作为返回值
// function create(){
// const a=100
// return function(){
// console.log(a)
// }
// }
// const fn=create()
// const a=200
// fn()//100
//函数作为参数
function print(fn){
const a=200
fn()
}
const a=100
function fn(){
console.log(a);
}
print(fn)//100
this
- 作为普通函数
- 使用call apply bind
- 作为对象方法
- 在class方法中调用
- 箭头函数
this的值在函数执行时决定
在方法中,this 表示该方法所属的对象。
如果单独使用,this 表示全局对象。
在函数中,this 表示全局对象。
在函数中,在严格模式下,this 是未定义的(undefined)。
在事件中,this 表示接收事件的元素。
类似 call() 和 apply() 方法可以将 this 引用到任何对象。
在 JavaScript 中函数也是对象,对象则有方法,apply 和 call 就是函数对象的方法。这两个方法异常强大,他们允许切换函数执行的上下文环境(context),即 this 绑定的对象。
在下面实例中,当我们使用 person2 作为参数来调用 person1.fullName 方法时, this 将指向 person2, 即便它是 person1 的方法:
var person1 = {
fullName: function() {
return this.firstName + " " + this.lastName;
}
}
var person2 = {
firstName:"John",
lastName: "Doe",
}
person1.fullName.call(person2); // 返回 "John Doe"
题目解答
this的不同应用场景,如何取值
- 当作普通函数被调用:返回window
- 使用call,apply,bind:传入什么绑定什么
- 作为对象方法调用:返回对象
- 在class的方法调用:返回实例
- 箭头函数:找他上一级作用域的this
手写bind函数
<script>
Function.prototype.bind1=function(){
//将参数拆解为数组
const args=Array.prototype.slice.call(arguments)
//获取this()数组第一项
const t = args.shift()
//fn1.bind(...)中的fn1
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);
</script>
实际开发中闭包的应用场景,举例说明
作用:
- 隐藏数据
如做一个简单的cache工具
<script>
//闭包隐藏数据,只提供API
function createCache(){
const data={}//闭包中的数据,被隐藏,不被外界访问
return{
set :function(key,val){
data[key]=val
},
get:function(key){
return data[key]
}
}
}
const c=createCache()
c.set('a',100)
console.log(c.get('a'));
</script>
十个a标签
考察块级作用域
<script>
//创建十个a标签,点击的时候弹出对应序号
let a
for(let i=0;i<10;i++){
a=document.createElement('a')
a.innerHTML=i+'<br>'
a.addEventListener('click',function(e){
e.preventDefault()
alert(i)
})
document.body.appendChild(a)
}
</script>