js面试题知识点全解(一作用域)
问题:
1.说一下对变量提升的理解
2.说明this几种不同的使用场景
3.如何理解作用域
4.实际开发中闭包的应用
知识点:
js没有块级作用域
只有函数和全局作用域,如下代码:
if(true){ var name='killua' //把name定义在块里和放在外面是一样的,等同于在外面声明一个变量name,在块内给name赋值 }//同等于下面的代码 //建议用下面方式写 var name if(true){ name='killua' } console.log(name) //打印出来killua //函数和全局作用域 var a=100 //定义全局作用域变量 function fn(){ var a=200 //在函数中定义变量不会污染外面定义的变量,只能函数里面用 console.log('fn', a) }
当前作用域没有定义某个变量,所以要去它的父级作用域找,这样的就是作用域链
//作用域链例子1 var a = 100 //自由变量 function fn(){ var b = 200 console.log(a) console.log(b) } fn() //作用域链例子2 var x =100 function F1(){ var y = 200 function F2(){ var z =300 console.log(x) console.log(y) console.log(z) } F2() } F1()
作用域和闭包-执行上下文
console.log(a); //undefined var a=10; //这种写法,因为a是全局变量。会把var a;提到最前面 /*以上代码等同于: var a; console.log(a); a=10;*/ fn("killua"); function fn(name){ console.log(name) } //函数声明会提前到最前面,所以可以先执行函数,再声明函数也可以 fn('killua') function fn(name){ console.log(this) // console.log(arguments) //参数 age=10 console.log(name, age) var age bar(100) function bar(num){ console.log(num) } //在函数内也会把函数声明,变量声明提到函数内部最前面 } //函数执行完输出 //killua 10 //100
this介绍:
this要在执行时才能确认,定义时无法确认
var a= { name = 'killua', fn: function(){ console.log(this.name) } } a.fn() //this===a a.fn.call({name:'L'}) //this==={name:'L'} var fn1 =a.fn fn1() //this===window
构造函数中的this
1 function Foo(name){ 2 this.name = name 3 } 4 var f = new Foo('killua') //实例化
对象中的this
1 var obj = { 2 name:'L' 3 printName: function(){ 4 console.log(this.name) 5 } 6 } 7 obj.printName() //作为对象属性来执行,this指向obj这个对象
普通函数中的this
1 function fn(){ 2 console.log(this) //作为一个普通函数执行,this === window 3 } 4 fn()
call apply bind
1 function fn1(name,age){ 2 console.log(this) 3 } 4 fn1.call({x:10},"killua",20) //call调用一个对象的一个方法,以另一个对象替换当前对象,这里把this替换成{x:10} 5 fn2.apply({x:10},['killua',20]) //apply和call方法一样,只是用数组的方式传递参数,call比较常用 6 var fn3 = function(name,age){ 7 console.log(this) 8 }.bind({y:200}) //.bind()方法和前两个一样,把this替换成{y:200},但是必须用在函数表达式,不能用在普通函数 9 fn3('killua',20)
以上知识点总结出题目内容
说一下对变量提升的理解:
1.变量定义 //变量声明会提前
2.函数声明(注意和函数表达式的区别) //函数声明提升
说明this几种不同的使用场景:
1.作为构造函数执行
2.作为对象属性执行
3.作为普通函数执行
4.call apply bind
如何理解作用域:
1.自由变量
2.作用域链,即自由变量的查找
3.闭包的两个场景