函数声明和函数表达式有什么区别?
ECMAScript规定了三种声明函数的方式(构造函数、函数声明、函数表达式)
- 构造函数(使用new来创建一个函数对象)
var hope = new Function("console.log('hello world');");
- 函数声明(使用function声明一个函数,声明的位置不影响调用的位置)
//函数声明
function oneStep () {
console.log("hello world")
}
//函数调用
oneStep()
- 函数表达式(声明必须放在调用之前)
var oneStep = function () {
console.log("hello world")
}
oneStep()
函数声明与函数表达式之间的区别就是函数表达式必须将声明放在调用之前,而函数声明则不用去顾忌这一点
变量的声明前置?函数的声明前置?
变量的声明前置
conslole.log(a);
var a=3;
//实际上会是这样
var a;
console.log(a);//undefined
a=1;
*/
函数的声明前置
sayHello("My lord");
founction sayHello(name) {
console.log(name);
}
//实际上会这样
founction sayHello(name) {
console.log(name);
}
sayHello("My lord");
arguments
ECMAScript中的参数在内部是用一个数组表示的,augument对象与数组类似,可以使用方括号访问它的每一个元素。而且关于argument,它的值永远与对应命名参数的值保持同步
js中函数的“重载”
ECMAScript函数不能像传统意义一样实现重载,因为它没有签名,其参数是由包含零或多个值得数组来表示的,没有签名真正的重载是不可能实现的。当定义了两个同名的函数,该名字属于后定义的函数,通过检查传入函数的参数类型和数量实现不同反应,可以模仿重载。
立即执行函数表达式是什么及其作用
用括号包含住函数体,或者包含在数组初始化器内,也可以用逗号也可以实现隔离作用域。
(function() {
var a = 1;
}) ()
console.log(a); //undefined
求n!,用递归来实现
function factor(n){
if(n<0){
console.log("请输入一个自然数");
} else if(n==0 || n==1){
return 1;
} else {
return n*factor(n-1)
}
}
以下代码输出什么
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, '男');
/*name:饥人谷
age:2
sex:男
0:"valley"
1:2
2:"男"
name valley */
getInfo('小谷', 3);
/*name:小谷
age:3
sex:undefined
0:"valley"
1:3
name valley*/
getInfo('男');
/*name:男
age:undefined
sex:undefined
0:valley
name valley
*/
写一个函数,返回参数的平方和
function sumOfSquares(){
for( i=0 i<=arguments.length i++) {
sum+=Math.pow(arguments[i],2);
}
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);
/*undefined, b is not defined
由于变量的声明前置,函数的声明前置,导致a声明了但未来得及赋值*/
如下代码的输出?为什么
sayName('world');
sayAge(10);
function sayName(name){
console.log('hello ', name);
}
var sayAge = function(age){
console.log(age);
};
/*hello world, sayAge is not function,因为该函数是以函数表达式的形式存在的,声明应该在调用之前*/
如下代码输出什么? 写出作用域链查找过程伪代码
var x = 10
bar()
function foo() {
console.log(x)
}
function bar(){
var x = 30
foo()
}
/*输出结果为:30,
1. globalContext = {
AO: {
x: 10
foo: function
bar: function
},
Scope: null
}
foo.[[scope]] = globalContext.AO
bar.[[scope]] = globalContext.AO
2. barContext = {
AO: {
x:30
}
}
//当调用foo()时,先从bar执行行下文的AO中找,找不到后再从bar的[[scope]]中找,找到后调用
3. fooContext = {
AO: {
x: 10
},
Scope: foo.[[scope]]
}
//调用foo()时,进入foo的执行上下文,所以console.log(x)是10
*/
如下代码输出什么? 写出作用域链查找过程伪代码
var x = 10;
bar()
function bar(){
var x = 30;
function foo(){
console.log(x)
}
foo();
}
/*输出结果为:30
1. golbalContext= {
AO:{
x: 10
bar: function
},
scope: null
}
bar[[scope]] = globalContext.AO
2. barContext={
AO:{
x: 10
foo: function
},
scope: bar.[[scope]] //globalContext.AO
}
foo[[scope]] = barContext.AO
3.fooContext={
AO:{},
Scope: foo.[[scope]] //barContext.AO
}
//所以console.log(x)是30
*/
以下代码输出什么? 写出作用域链的查找过程伪代码
var x = 10;
bar()
function bar(){
var x = 30;
(function (){
console.log(x)
})()
}
/*输出结果为:30
1. globalContext= {
AO:{
x: 10
bar: function
},
Scope: null
}
bar[[scope]] = golbalContext.AO
2. barContext={
AO:{
x:30
匿名函数:function
}
Scope:bar.[[scope]] //barContext.AO
}
匿名函数.[[scope]] = barContext;
3. 匿名函数= {
AO: {}
Scope: 匿名函数[[scope]] //barContext.AO
}
所以console.log(x)为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)
/*输出结果为:undefined,5,1,6,20,200
1. golbalContext ={
AO:{
X:1
fn:function
fn3:function
},
Scope:null
}
fn[[scope]] = globalContext.AO
fn3[[scope]] = globalContext.AO
2.fnContext ={
AO:{
a:undefined
fn2: function
}
Scope:fnConrtext[[scope]]
}
fn2[[scope]] = fnContext.AO
3.fnContext ={
AO:{
a:5
fn2: function
}
Scope:fnConrtext[[scope]]
}
fn2[[scope]] = fnContext.AO
4. fnContext ={
AO:{
a: 6
fn2: function
}
Scope:fnConrtext[[scope]]
}
fn2[[scope]] = fnContext.AO
5. fn3Context ={
AO:{}
Scope:globalConrtext[[scope]]
}
fn3[[scope]] = globalContext.AO
6. fn2Context= {
AO: {}
Scope: fn3Context.AO
}
fn2[[scope]] = fnContent.AO
7. fnContext ={
AO:{
a: 20
fn2: function
}
Scope:fnConrtext[[scope]]
}
fn2[[scope]] = fnContext.AO
8. fnContext ={
AO:{
a: 200
fn2: function
}
Scope:fnConrtext[[scope]]
}
fn2[[scope]] = fnContext.AO
*/