1、函数声明和函数表达式有什么区别
函数声明格式:
functionName();
function functionName(参数){
console.log('hello')
}
声明不必放到调用的前面
函数表达式格式:
var functionName = function (参数){
console.log('hello')
}
functionName();
等价于
var functionName
functionName();
var functionName = function(){
console.log('hello')
}
声明必须放到调用的前面
2、什么是变量的声明前置?什么是函数的声明前置?
变量的声明前置就是把变量的声明提升到当前作用域的最前面。
函数的声明前置就是把整个函数提升到当前作用域的最前面(位于前置的变量声明后面),代码执行前会先生成该函数,然后再执行语句。
console.log(a); //undefined,在一个作用域下,var声明的变量和function声明的函数会前置
var a = 1;
console.log(b); // b is not defined
3、arguments 是什么?
arguments 是一个类似数组的对象, 对应于传递给函数的参数。对象仅在函数内部有效,在函数外部调用 arguments 对象会出现一个错误。
4、函数的“重载”怎样实现?
在 JS 中,没有重载! 同名函数会覆盖。但可以在函数体针对不同的参数调用执行相应的逻辑
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');
5、立即执行函数表达式是什么?有什么作用?(题13)参考
(function(){
var a = 1;
})()
console.log(a); //undefined
其他写法
(function fn1() {});
// 在数组初始化器内只能是表达式
[function fn2() {}];
// 逗号也只能操作表达式
1, function fn3() {};
作用: 隔离作用域。
一是不必为函数命名,避免了污染全局变量;
二是IIFE内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量。
6.1、求n!(n的阶乘),用递归来实现
function factor(n){
if(n === 1 || n==0) {
return 1
}else if(n < 1){
return false
}
return n * factor(n-1)
}
factor()
6.2 求 1+2+...+n 的值
function sum(n){
if(n === 1) {
return 1
}
return n + sum(n-1)
}
sum()
7. 以下代码输出什么?
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:男;["饥人谷",2,"男"];name valley
getInfo('小谷', 3); // name:小谷 age:3 sex:undefined;["小谷",3];name valley
getInfo('男'); // name:undefined age:undefined sex:男;["男"];name valley
8. 写一个函数,返回参数的平方和?
function sumOfSquares(){
var a = 0;
for(i = 0; i < arguments.length; i++) {
a += arguments[i] * arguments[i];
}
return r;
}
var result = sumOfSquares(2,3,4)
var result2 = sumOfSquares(1,3)
console.log(result) //29
console.log(result) //10
10. 如下代码的输出?为什么
sayName('world'); //hello world 函数声明前置
sayAge(10); //报错:sayAge is not a function 函数表达式不前置
function sayName(name){
console.log('hello ', name);
}
var sayAge = function(age){
console.log(age);
};
11. 如下代码输出什么? 写出作用域链查找过程伪代码
var x = 10
bar()
function foo() {
console.log(x) // 10
}
function bar(){
var x = 30
foo()
}
作用域链
1\全局
globalContext = {
AO:{
x:10
foo:function(){}
bar:function(){}
}
scope:null
}
foo.[[scope]]=globalContext.AO
bar.[[scope]]=globalContext.AO
2\
barContext = {
AO : {
x:30
}
scope:bar.[[scope]]=globalContext.AO
}
3\
fooContext = {
AO:{}
scope:globalContext.AO
}
12. 如下代码输出什么? 写出作用域链查找过程伪代码
var x = 10;
bar()
function bar(){
var x = 30;
function foo(){
console.log(x) //30
}
foo();
}
作用域链
1\
globalContext = {
AO:{
x:10
bar:function(){}
}
}
bar.[[scope]]=globalContext.AO
2\
barContext = {
AO:{
x:30
foo:function(){}
}
scope:globalContext.AO
}
foo.[[scope]]:barContext.AO
3\
fooContext = {
AO:{}
scope:barContext.AO
}
13. 以下代码输出什么? 写出作用域链的查找过程伪代码
var x = 10;
bar()
function bar(){
var x = 30;
(function (){
console.log(x) //30
})()
}
作用域链
1\
globalContext = {
AO:{
x:10
bar:function(){}
}
}
bar.[[scope]]:globalContext.AO
2\
barContext = {
AO:{
x:30
foo:function(){}
}
scope:globalContext.AO
}
foo.[[scope]]:barContext.AO
3\
fooContext = {
AO:{}
scope:barContext.AO
}
14. 以下代码输出什么? 写出作用域链查找过程伪代码
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
输出:undefined 5 1 6 20 200
作用域链
1\
globalContext = {
AO:{
a:1>200
fn:function(){}
fn3:function(){}
}
}
fn.[[scope]]:globalContext.AO
fn3.[[scope]]:globalContext.AO
2\
fnContext = {
AO:{
a:5 >6>20
fn2:function(){}
}
scope:globalContext.AO
}
fn2.[[scope]]:fnContext.AO
3\
fn3Context = {
AO:{}
scope:globalContext.AO
}
4\
fn2Context = {
AO:{}
scope:fnContext.AO
}