Q1:函数声明和函数表达式的区别
函数声明: function doSomething( ){ statement1;statement2;statement3; }
函数表达式:var aBc = function( ){ console.log('hello'); }
函数声明和函数表达式非常的类似,在解析时,函数声明会被前置,是语句;而函数表达式是表达式,赋值给变量,不会被前置。
Q2:什么是声明前置
- 在同一个作用域下,var声明的变量与function声明的函数会前置。
- 函数表达式和var声明的变量没有任何区别。
- 在发生命名冲突时,会首先前置变量,再会发生第二个变量值覆盖相同命名的变量值。
Q3:求n!,用递归来实现
function factor(n){
if(n === 1) {
return 1
}
return n * factor(n-1)
Q4:什么是立即执行的函数表达式?有什么作用?
立即执行的函数表达式:声明了此函数后立即自动调用。
语法:
(function fn1() {});
[function fn2() {}];
1, function fn3() {};
作用:创建独立的作用域,防止变量被污染。
Q5:如下代码输出什么? 写出作用域链查找过程伪代码
var x = 10
bar()
function foo() {
console.log(x)
}
function bar(){
var x = 30
foo() // 输出什么
}
答:1. globalContext = {
AO: {
x: 10
foo: function(){}
bar: function(){}
},
}
foo.[[scope]] = globalContext.AO
bar.[[scope]] = globalContext.AO
2. fooContext = {
AO: { }
Scope:foo.[[Scope]] //console.log(foo)=10
3.barContext={
AO:{
x:30
}
Scope:bar.[[Scope]] //console.log(bar)=30
Q7. 如下代码输出什么? 写出作用域链查找过程伪代码?
var x = 10;
bar()
function bar(){
var x = 30;
(function (){
console.log(x)
})()
}
答:1.globalContext = {
AO: {
x: 10
bar: function(){}
}
}
bar.[[scope]] = globalContext.AO
2.barContext = {
AO: {
x: 30,
foo: function
},
Scope:bar.[[scope]]
}
foo.[[scope]] = barContext.AO //console.log(x)=10
3. fooContext = {
AO: {}
scope:foo.[[scope]] //console.log(x)=30
}
Q8. 如下代码输出什么? 写出作用域链查找过程伪代码?
var a = 1;
function fn(){
console.log(a); // undefined
var a = 5;
console.log(a); // 5
a++;
var a;
fn3();
fn2();
console.log(a); // 20
function fn2(){
console.log(a); // 6
a = 20;
}
}
function fn3(){
console.log(a) // 1
a = 200;
}
fn();
console.log(a); // 200
答:1.globalContext = {
AO: {
a: 1,
fn: function,
fn3:function,
}
fnContext.Scope = globalContext;
fn3Context.Scope = globalContext;
fnContext = {
AO:{
a: undefined, //fn第一个console.log(a)
fn2: funtion,
},
Scope: globalContext.AO,
}
fn2Context.Scope = fnContext;
fn2Context = {
AO:{
},
Scope: fnContext,
}
fn3Context = {
AO:{
},
Scope: globalContext,
}
2.fnContext{
AO: {
a: 5 // 第二个console.log(a)的输出值
fn2: function,
},
Scope: globalContext,
}
3. globalContext = {
AO:{
a: 1, //fn3的console.log(a)
fn: function,
fn3: function,
},
Scope: null,
}
fnContext = {
AO:{
a: 6, //a++之后的值
fn2: funtion,
},
Scope: globalContext,
}
fn3Context = {
AO:{
},
Scope: globalContext,
}
4.globalContext = {
AO:{
a: 200, //fn3的a = 200
fn: function,
fn3: function,
},
Scope: null,
}
fnContext = {
AO:{
a: 6, //fn2的console.log(a)
fn2: funtion,
},
Scope: globalContext,
}
fn2Context = {
AO:{
},
Scope: fnContext,
}
fn3Context = {
AO:{
},
Scope: globalContext,
}
5.fnContext = {
AO:{
a: 20, //fn2里a = 20;fn的第三个console.log(a)
fn2: funtion,
},
Scope: globalContext,
}
6.globalContext = {
AO:{
a: 200, //全局最后的console.log(a)
fn: function,
fn3: function,
},
Scope: null,
}
输出结果依次为: undefined,5,1,,6,20,200
Q9:以下代码输出什么?画出执行过程作用域伪代码(难度五颗星,用兴趣的同学可选做)
function fn(){
var x = 1;
function fn2(){
x++;
console.log(x) ;
}
return fn2
}
var foo = fn()
var bar = fn()
foo()
bar()
foo()
未完成,完成后在简书补充