一、函数声明和函数表达式有什么区别
1.函数声明:
-
函数调用可以发生在函数声明之前;示例:
因为‘提升’了函数声明,函数调用可在函数声明之前。
2.函数表达式:
-
函数调用只能在函数表达式后面,不能在函数表达式前面;示例:
变量getName还未保存对函数的引用,函数调用必须在函数表达式之后。
3.区别:js引擎在解析JavaScript代码时会进行“函数声明提升”当前执行环境(作用域)上的函数声明,而函数表达式必须等到JavaScript引擎执行到它所在的位置时,才会至上而下的解析函数表达式。
二、什么是变量的声明前置?什么是函数的声明前置
1.变量的声明前置:JavaScript引擎的工作方式是,先解析代码,获取被声明的变量,然后再一行一行的运行。这造成的结果就是所有变量的声明语句,都会被提升到代码的头部,这就叫做变量提升。
调用函数getName() 打印的结果为 undefined ,因为函数作用域的特性,函数中申明的变量(但不涉及赋值)被“提前”至函数的顶部,因此打印的结果为 undefined ,其运行过程等价于实例2,如下:
2.函数的声明前置:函数的调用可以在函数声明之前。
三、arguments 是什么
在函数内部可以使用arguments对象获取到该函数的所有传入参数。
通过访问arguments对象的length属性可以获知有多少个参数传递给了函数
四、函数的重载怎样实现
1.重载是很多面向对象语言实现多态的手段之一,在静态语言中确定一个函数的手段是靠方法签名——函数名+参数列表,也就是说相同名字的函数参数个数不同或者顺序不同都被认为是不同的函数,称为函数重载。
2.JavaScript 中没有函数重载的概念,因为函数名类似于指针,当有同名函数名的时候后声明的函数会覆盖前声明的函数。但是可以通过处理传入的参数来实现类似重载的效果。当需要传入不同个数的参数时,可以把参数以键值对的形式用一个对象字面量封装起来,然后函数参数只传入那一个对象即可。函数内部使用 if-else 来判断具体某一个参数存在与否来做相应的处理。如果是简单的数字类型参数相加的函数,也可以遍历 arguments 来相加每一个结果。
五、立即执行函数表达式是什么?有什么作用
1.立即执行函数表达式:( function(){…} )()和( function (){…} () )
2.作用:
- 创建作用域,防止命名冲突。
- 一些库的外层用这种形式包起来防止作用域污染。
- 运行一些只执行一次的代码。
- 用闭包保存状态。
六、什么是函数的作用域链
1.JavaScript中,变量的作用域有分全局作用域和局部作用域两种。
- 全局作用域:在代码的任何地方都能访问到的对象拥有全局作用域。
- 局部作用域:和全局作用域相反,局部作用域一般只在固定的代码片段内可以访问,最常见的例如函数内部,所以有人也把这种作用域称作函数作用域。
2.每个函数都是有自己的作用域的,比如在一个函数A中创建的函数B的作用域就是在A中,如果在比A更广的空间去调用B是不可以的,那么A也有一个作用域,可能是全局window,也可能是自己的父级函数。这样一层一层的作用域连接起来就是一条函数的作用域链。
七、以下代码输出什么?
八、写一个函数,返回参数的平方和?
九、如下代码的输出?为什么
十、如下代码的输出?为什么
十一、如下代码的输出?为什么
十二、如下代码的输出?为什么
十三、如下代码的输出?为什么
原因:由于同一个作用域中,定义同一个名字的变量和方法时,变量赋值会覆盖方法的赋值,因此此时解析器并不能够识别fn为函数,但是在打印时又以函数的方式打印,因此会报错。
十四、如下代码的输出?为什么
原因:for是循环语句,不是函数,所以不会前置,其定义的变量自然就是全局变量,所以能够被解析,正常顺序执行并显示。