函数声明和函数表达式有什么区别
-
函数声明(Function Declaration) 示例代码:
function abc(){ //中间是操作 }
-
函数表达式(Function Expression) 示例代码:
var abc=function(){ //中间是操作 }
区别:用函数声明创建的函数可以在函数解析后调用(解析时进行等逻辑处理);而用函数表达式创建的函数是在运行时进行赋值,且要等到表达式赋值完成后才能调用。通俗点讲:函数声明不是必须放到调用的前面;函数表达式的调用必须在赋值(声明)之后。
什么是变量的声明前置?什么是函数的声明前置
在同一个作用域下,var声明的变量和function声明的函数会前置。
js代码加载时候按照这样的规则:遇到var声明变量或者function声明函数,无论赋值与否,首先执行给他们定义的操作。前置顺序从上到下,先前置,再赋值。
arguments 是什么
arguments 是JavaScript里的一个内置对象,所有主要的js函数库都利用了arguments对象。
所有的函数都有属于自己的一个arguments对象,它包括了函所要调用的参数。他不是一个数组,如果用typeof arguments,返回的是’object’。虽然我们可以用调用数据的方法来调用arguments。比如length,还有index方法。但是数组的push和pop对象是不适用的。
函数的"重载"怎样实现
首先简单描述一下编程中函数的重载的理解:代码里可以定义多个同名函数,根据传入的参数的方式不同,可以自动去匹配所需要的函数。
然而在js里面,没有重载的概念。同名的函数会被覆盖掉。但可以在函数体针对不同的参数调用执行相应的逻辑。
-
js中实现"重载"可以定义一个函数,通过判断函数的参数来实现"重载",例如:
function abc(a,b,c) { if(a){ console.log(a) } if(b){ console.log(b) } if(c){ console.log(c) } }
立即执行函数表达式是什么?有什么作用
立即自行函数表达式是一种立即调用函数的写法,通过函数表达式的方式声明函数并直接调用。例如:
(function(){
console.log("我是立即执行的函数表达式!")
}())
作用:不必为函数命名,避免了污染全局变量;立即执行函数表达式内形成了一个单独的作用域,可以封装一些外部无法读取的私有变量。
求n!,用递归来实现
function diGui(n) {
if(n===1){
return 1
}else{
return n = n*diGui(n-1)
}
}
diGui(10)
以下代码输出什么?
function getInfo(name, age, sex){
console.log('name:',name);
console.log('age:', age);
console.log('sex:', sex);
console.log(arguments);
arguments[0] = 'valley';
console.log('name', name);
}
getInfo('饥人谷', 2, '男');
getInfo('小谷', 3);
getInfo('男');
输出结果如下:
ame: 饥人谷
age: 2
sex: 男
Arguments[3]
name valley
name: 小谷
age: 3
sex: undefined
Arguments[2]
name valley
name: 男
age: undefined
sex: undefined
Arguments[1]
name valley
写一个函数,返回参数的平方和?
function sumOfSquares(){
var sum = 0; //定义sum
for(i = 0; i < arguments.length; i++){
sum += arguments[i]*arguments[i]; //遍历参数进行平方和累加
}
return sum;
}
var result = sumOfSquares(2,3,4)
var result2 = sumOfSquares(1,3)
console.log(result) //29
console.log(result2) //10
如下代码的输出?为什么
console.log(a);
var a = 1;
console.log(b);
对以上代码做变量提升
var a
console.log(a); //a没有赋值,所以打印出undefined
a = 1
console.log(b);//b没有声明,所以会报错
如下代码的输出?为什么
sayName('world');
sayAge(10);
function sayName(name){
console.log('hello ', name);
}
var sayAge = function(age){
console.log(age);
};
输出结果只有hello world,因为函数声明中函数调用可以放在声明前,
函数表达式中函数必须先声明,后调用。
如下代码输出什么? 写出作用域链查找过程伪代码
var x = 10
bar()
function foo() {
console.log(x)
}
function bar(){
var x = 30
foo()
}
-
函数作用域链
1. globalContext = { AO: { x: 10 foo:function bar:function } Scope: null } //声明foo时得到下面 foo.[[scope]] = globalContext.AO //声明bar时得到下面 bar.[[scope]] = globalContext.AO //PS: 在当前的执行上下文内声明的函数,这个函数的[[scope]]就执行当前执行上下文的 AO 2. barContext: AO: { x:30;// 必须是var x =30才有 } Scope: bar.[[scope]] = globalContext.AO 3. fooContext: AO: {} Scope:foo.[[scope]] = globalContext.AO
根据函数作用域链来分析代码,首先定义了一个全局变量x:10,执行函数bar(),在bar()函数中定义了局部变量x:30,调用函数foo(),执行console.log(x),x的值首先在fooContex的AO中寻找,AO中没有,再到Scope中寻找,得出x:10,所以最终打印结果为10
如下代码输出什么? 写出作用域链查找过程伪代码
var x = 10;
bar()
function bar(){
var x = 30;
function foo(){
console.log(x)
}
foo();
}
-
函数作用域链
1.globalContext = { AO: { x: 10 bar:function } Scope:null } 2.barContext = { AO: { x: 30 foo: function } Scope: bar.[[scope]] = globalContext.AO } 3.fooContext = { AO: {} Scope: foo.[[scope]] = barContext.AO }
执行console.log(x)时,在fooContext中寻找x的值,AO中没有声明x的值,继续指向barContext.AO,x取值为30,所以最终结果为30
以下代码输出什么? 写出作用域链的查找过程伪代码
var x = 10;
bar()
function bar(){
var x = 30;
(function (){
console.log(x)
})()
}
-
函数作用域链
1.globalContext = { AO: { x: 10 bar: function } Scope: null } 2.barContext = { AO: { x: 30 (): function } Scope: bar.[[scope]] = globalContext.AO } 3.()Context = { AO:{} Scope: ().[[scope]] = barContext.AO }
输出结果为30
以下代码输出什么? 写出作用域链查找过程伪代码
var a = 1;
function fn(){
console.log(a)
var a = 5
console.log(a)
a++
var a
fn3()
fn2()
console.log(a)
function fn2(){
console.log(a)
a = 20
}
}
function fn3(){
console.log(a)
a = 200
}
fn()
console.log(a)
-
函数作用域链
1.globalContext = { AO: { a: 1 fn: function fn3: function } Scope:null } 2.fnContext = { AO: { a: 6 } Scope: fn.[[scope]] = globalContext.AO } 3.fn2Context = { AO: { a: 20 } Scope: fn2.[[scope]] = fnContext.AO } 4.fn3Context = { AO: { a: 200 } Scope: fn3.[[scope]] = globalContext.AO }
输出结果为:undefined,5,1,6,20,200