函数与作用域
2017-12-06 本文已影响0人
饥人谷_Coziz
函数声明和函数表达式有什么区别
函数声明:function one(){}
函数表达式:var one = function(){}
函数声明使用function来进行声明,函数声明前置,所以不论执行语句的位置前后皆可调用该函数。但是函数表达式是var声明在调用时一定要在var 声明的后面。
函数声明的函数名在全局变量和局部变量都可以调用,但是函数表达式的函数名只有函数自身的局部变量能用,调用函数表达式用的是变量名。
什么是变量的声明前置?什么是函数的声明前置
- 变量的声明前置:指的是解析器将当前作用域内声明的所有变量放到作用域的前面,但是,只有变量的声明被前置了(初始值都为undefined),而赋值操作还在原来的顺序。
- 函数的声明前置:JavaScript解释器允许在函数声明之前使用函数,整个函数被前置了,所以调用不管在函数前面还是后面都可以执行。
arguments 是什么
类数组对象:在函数内部可以使用arguments对象获取到该函数的所有传入参数。
函数的"重载"怎样实现
JavaScript中是没有真正的重载的。
重载举例:要对两个数求和,那我们就用支持重载的语言自定义一个函数sum来实现求和功能,但是这两个数可以是整数,可以是小数。此时就可以利用重载来定义函数名相同,但是函数类型不同(一个为整数类型,一个为小数类型)、形参类型不同(一个为整型形参,一个为浮点型形参)的两个函数。结果就是:调用sum()函数,无论实参是整数还是小数,都可以实现正确的求和功能。
JavaScript中,命名重复会造成覆盖,所以不会有真的重载,但是可以在函数体内针对不同的参数调用执行相应的逻辑,举例如下:
var val=function printPeopleInfo(name,age,sex){
if(name){
console.log(name);
}
if(age){
console.log(age);
}
if(sex){
console.log(sex);
}
}
val("summer",2017);//只有两个实参按顺序对应前两个形参:name、age,但是输出结果不会在输出第三个参数为undefined
val("summer",2017,"female");
立即执行函数表达式是什么?有什么作用
立即执行函数表达式的两种写法:
通常情况下,只对匿名函数使用这种“立即执行的函数表达式”。它的目的有两个:
(function(){
...
})();
(function(){
...
}());
- 是不必为函数命名,避免了污染全局变量;
- 是IIFE(立即执行函数表达式)内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量。
求n!,用递归来实现
function factorial(n) {
if (n <=1) {
return 1;
} else {
return n * factorial(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: 男
['饥人谷',2,'男']
name valley
*/
getInfo('小谷', 3);
/*
name: 小谷
age: 3
sex: undefined
['小谷',3]
name valley
*/
getInfo('男');
/*
name: 男
age: undefined
sex: undefined
['男']
name valley
*/
写一个函数,返回参数的平方和?
function sumOfSquares(){
var sum=0;
for(var i=0;i<arguments.length;i++){
sum=sum+arguments[i]*arguments[i];
}
console.log(sum);
}
var result = sumOfSquares(2,3,4)
var result2 = sumOfSquares(1,3)
console.log(result) //29
console.log(result2) //10
如下代码的输出?为什么
console.log(a); // 1
var a = 1;
console.log(b); //b is not defined,没有声明变量b
如下代码的输出?为什么
sayName('world');
sayAge(10);
function sayName(name){
console.log('hello ', name); //hello world
}
var sayAge = function(age){
console.log(age); // sayAge is not a function,var sayAge 变量声明前置,但只会声明此变量不会将其赋值为函数,所以函数 sayAge 的调用必须在函数赋值之后。
};
如下代码输出什么? 写出作用域链查找过程伪代码
var x = 10
bar()
function foo() {
console.log(x)
}
function bar(){
var x = 30
foo()
}
// 输出10
globalContent={
AO:{
x:10,
foo:function,
bar:function
}
}
foo.[[scope]]=globalContent.AO;
bar.[[scope]]=globalContent.AO;
barContent={
AO:{
x:30
}
scope:globalContent.AO;
}
fooContent={
AO:{}
scope=globalContent.AO;
}
如下代码输出什么? 写出作用域链查找过程伪代码
var x = 10;
bar()
function bar(){
var x = 30;
function foo(){
console.log(x)
}
foo();
}
//输出 30
globalContent={
AO:{
x:10,
bar:function
}
}
foo.[[scope]]=barContent.AO;
bar.[[scope]]=globalContent.AO;
barContent={
AO:{
x:30
foo:function,
}
scope:globalContent.AO;
}
fooContent={
AO:{}
scope=barContent.AO;
}
以下代码输出什么? 写出作用域链的查找过程伪代码
var x = 10;
bar()
function bar(){
var x = 30;
(function (){
console.log(x)
})()
}
// 输出30
globalContext = {
AO:{
x: 10,
bar: function
}
scope:null
}
bar.[[scope]] = globalContext.AO
barContext = {
AO: {
x: 30;
function: function
}
scope: globalContext.AO
}
function[[scope]] = globalContext.AO
functionContext = {
AO: {}
scope: barContext.AO
}
以下代码输出什么? 写出作用域链查找过程伪代码
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
globalContext = {
AO: {
a:1 ->200
fn:function
fn3:function
}
Scope:null
}
fn[[Scope]]=globlaContext.AO
fn3[[Scope]]=globlaContext.AO
fnContext = {
AO:{
a:undefined ->5 ->6 ->20
fn2:function
}
Scope:globlaContext.AO
}
fn2[[Scope]]:fnContext.AO
fn3Context = {
AO: {}
Scope:globlaContext.AO
}
fn2Context = {
AO: {}
Scope: fnContext.AO
}