面试题
1、说一下对变量提升的理解
2、说明this几种不同的使用场景
3、创建10个a 标签,点击的时候弹出来对应的序号
4、如何理解作用域
5、实际开发中闭包的作用
知识点
1、执行上下文
2、this
3、作用域
4、作用域链
5、闭包
一、变量提升
1、变量定义 2、函数声明(与函数表达式的区别)
console.log(a);
var a=10;
会把var a提前,并且初始化为undefined
fn('zhangsan');
function fn(name){
age=20
console.log(name,age)
var age
}
函数的声明提前
二、this
要执行时确认,定义时无法确认
1、作为构造函数执行(实例对象)
function Foo(name){
this.name=name;
}
var f=new Foo('zhangsan')
console.log(f.name);
2、作为对象属性执行(对象)
var obj={
name:'A',
printName:function(){
console.log(this.name)
}
}
obj.printName();
3、作为普通函数执行(window)
function fn(){
console.log(this)
}
fn()
4、call 、apply、bind()第一个参数
function fn1(name,age){
alert(name)
console.log(this)
}
fn1.call({x:100},'zhangsan',12)
var fn2=function(name,age){
alert(name)
console.log(this)
}.bind({y:200})
//.bind必须是表达式
fn2('zhangsan',12)
三、作用域
1、es6中块级作用域,js5中没有块级作用域
if(true){
var name="zhangsan"
}
console.log(name)
2、函数作用域和全局作用域
四、作用域如何理解?
1、自由变量
定义:当前作用域没有定义的变量,即为‘自由变量’,找作用域时,看父级作用域在哪定义的,哪个函数定义了它,作用域就是哪个函数,不是执行时的作用域。
2、作用域链
定义:自由变量查找时,向它的父级一级一级的找
var a=100
function fn(){
var b=200
console.log(a)
console.log(b)
}
fn()
3、闭包
场景一、函数作为返回值
function F1(){
var a=100 //在这定义的父级作用域中的变量
return function(){
console.log(a)
}
}
var f1=F1()
var a=200//全局变量
f1()
场景二、函数作为参数传递
function F1(){
var a=100
return function(){
console.log(a)
}
}
var f1=F1()
var a=200
function F2(fn){
var a=200
fn()
}
F2(f1);
五、创建10个a标签
var i
for(i=0;i<10;i++){
(function (i){
//函数作用域
var a=document.createElement('a');
a.innerHTML=i+'<br>'
a.addEventListener('click',function(e){
e.preventDefault()
alert(i)//自由变量,要去父作用域获取值
})
document.body.append(a);
})(i)
}
六、实际中闭包的作用
用于封装变量,收敛权限
function isFirstLoad(){
var _list=[]
return function (id){
if(_list.indexOf(id)>=0){
return false
}else{
_list.push(id)
return true
}
}
}
var firstLoad=isFirstLoad()
console.log(firstLoad(10));
console.log(firstLoad(10));
console.log(firstLoad(20));
console.log(firstLoad(20));
//你在isFirstLoad函数外面,根本不可能修改内部变量_list的值