函数声明和函数表达式有什么区别
- 函数声明在JavaScript解析时进行函数提升,因此在同一个作用域内,不管函数声明在哪里定义,该函数都可以进行调用。
- 函数表达式的值是在JavaScript运行时确定,并且在表达式赋值完成后,该函数才能调用。这个微小的区别,可能会导致JavaScript代码出现意想不到的bug,让你陷入莫名的陷阱中。
什么是变量的声明前置?什么是函数的声明前置
-
变量声明前置就是在一个作用域块中,所有的变量都被放在块的开始出声明。
console.log(i); var i =1; //打印出 undefined。而不是报错,是因为var i;已经前置。
上面代码相当于:
var i; console.log(i); i = 1;
-
JavaScript引擎将函数名视同变量名,所以采用function声明函数时,整个函数会像var声明变量一样,被提升到代码头部。
test(1); function test(i){ console.log(i); }; //打印值为 1. 因为整个函数都前置。
上面代码相当于:
function test(i){ console.log(i) }; test(1); //输出值为1
arguments 是什么
-
arguments是一个类数组的本地对象,你可以使用arguments获取到该函数的所有传入参数。
function getInfo(name, age, sex){ console.log('name:',name); console.log('age:',age); console.log('sex:',sex); arguments[1]= 23; console.log('age:',age); } getInfo('bily', 22, 'man'); //输出: name:bily age:22 sex:man age: 23
函数的重载怎样实现
在 JavaScript 中没有重载! 同名函数会覆盖。但可以在函数体针对不同的参数调用执行相应的逻辑。
function printPeopleInfo(name, age, sex){
if(name){
console.log(name);
}
if(age){
console.log(age);
}
if(sex){
console.log(sex);
}
}
printPeopleInfo('Byron', 26);
printPeopleInfo('Byron', 26, 'male');
立即执行函数表达式是什么?有什么作用
-
创建只使用一次的函数,并立即执行它。
-
创建闭包,保存状态,隔离作用域。
-
作为独立模块存在,防止命名冲突,命名空间注入。
写法1 // 推荐写法 (function() { console.log('hello','jijrengu'); } () ); 其他写法 (function() { console.log('hello','jijrengu'); } ) ();
作用: 隔离作用域
求n!,用递归来实现
求 n 的阶乘 n!
function factor(n){
if(n === 0 || n === 1) {
return 1
}
return n * factor(n-1)
}
factor(5)
求 1+2+...+n 的值
function sum(n){
if(n === 1) {
return 1
}
return n + sum(n-1)
}
sum(10)
以下代码输出什么?
代码1.jpg 代码1答案.jpg写一个函数,返回参数的平方和?
代码2.jpg 代码2答案.jpg如下代码的输出?为什么
代码3.jpg上面代码相当于:
var a; // 因为变量提升,var a;前置
console.log(a); // 输出undefined
a = 1; // a=1未前置
console.log(b); // 报错不存在, b 未声明未赋值(不存在),打印b就会报错
如下代码的输出?为什么
代码4.jpgsayName('world');
sayAge(10);
function sayName(name){
console.log('hello ', name);
}
var sayAge = function(age){
console.log(age);
};
// "hello" "world" 因为函数声明提前,将整个函数前置,所以执行代码能正常输出。
// "sayAge is not a function" sayAge虽然因变量提升已经被声明,
但是sayAge(10) 是函数的调用方式,所以输出 is not a function
如下代码输出什么? 写出作用域链查找过程伪代码
代码5.jpgglobalContext = {
AO: {
x: 10,
foo: function,
bar: function;
}
}
foo.[[scope]] = globalContent.AO;
bar.[[scope]] = globalContext.AO;
barContext = {
AO: {
x: 30
},
scope: globalContext.AO;
}
fooContext = {
AO: {
}
scope: globalContext.AO;
}
// foo()输出: 10
如下代码输出什么? 写出作用域链查找过程伪代码
6.jpg globalContext = {
AO: {
x: 10,
bar: function;
}
}
bar.[[scope]] = globalContext.AO;
barContext = {
AO: {
x: 30
foo: function
},
scope: globalContext.AO;
}
foo.[[scope]] = barContext.AO;
fooContext = {
AO: {
}
scope: barContext.AO;
}
// foo()输出30
以下代码输出什么? 写出作用域链的查找过程伪代码
代码7.jpg globalContext = {
AO: {
x: 10
bar: function
},
Scope: null
}
bar.[[scope]] = globalContext.AO
barContext = {
AO: {
x: 30,
function
},
Scope: bar.[[scope]] //globalContext.AO
}
function.[[scope]] = barContext.AO
functionContext = {
AO: {
},
Scope: function.[[scope]] // barContext.AO
}
输出为30
以下代码输出什么? 写出作用域链查找过程伪代码
代码8.jpg globalContext = {
AO: {
a: 1
fn: function
fn3: function
},
Scope: null
}
fn.[[scope]] = globalContext.AO
fn3.[[scope]] = globalContext.AO
fnContext = {
AO: {
a: undefined,
fn2: function,
};
Scope: fn.[[scope]] //globalContext.AO
}
fn2.[[scope]] = fnContext.AO
fn3Context = {
AO:{
a: 200,
},
Scope:fn3.[[scope]]//globalContext.AO
}
fn2ConText = {
AO:{
a: 20,
},
Scope:fn2.[[scope]]//fnContext.AO
}
网友评论