函数和作用域
2017-10-06 本文已影响0人
Lucien_d70a
函数声明和函数表达式有什么区别?
- 函数声明:
function f(){} f()
- 函数表达式:
var f=function (){} f()
区别:
1.函数声明可以看作是函数的初始化,函数的表达式是把一个函数赋值给一个变
量。
2.函数声明 调用 可以放声明前面。 函数表达式 调用 要放到表达式后面。
什么是变量的声明前置?什么是函数的声明前置?
-
变量声明前置:JavaScript引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,然后给他初始值undefined,然后才逐句执行程序,这就叫做“变量提升”,也即“变量的声明前置”。
-
函数的声明前置:函数声明会被提升到作用域的最前面,即使写代码的时候是写在最后面,也还是会被提升至最前面
//预解析的时候会 var a=undefined
console.log(a)//undefined
var a=1
- 当遇到函数声明的时候,浏览器就会认为这就是一个函数,然后就会提前声明。所以调用函数声明在前面也可以。
//预解析的时候会 function f(){} 我是一个函数!!!
f()//"我爱饥人谷"
function f(){
console.log("我爱饥人谷")
}
f()//"我爱饥人谷"
- 所以,函数表达式 调用 不能在 声明前面, 不然就会得到 报错。
//预解析的时候var f=undefined
f()//报错
var f=function (){
console.log("hi")
}
arguments 是什么?
- argument是类数组对象,每个函数中都存在argument对象,argument并不是一个真正的数组,所以不具备除length属性之外的属性,这个对象维护这所有传入该函数的参数列表。
函数的"重载"怎样实现?
- JS中没有函数的重载。同名函数会被覆盖。但可以在函数体针对不同的参数调用执行相应的逻辑。
function fn(name,age,sex){
if(name){
return name;
}
if(age){
return age;
}
if(sex){
return sex;
}
}
fn("方方",18,"女")//"方方" 18 "女"
fn("方方",18)//"方方" 18
立即执行函数表达式是什么?有什么作用
- 立即执行函数就是当我们在定义了函数之后需要立即执行的函数。
- 立即执行函数:
(function (){}())
- 作用: 隔离作用域。
- 因为JavaScript有很多致命缺陷,以致于各类淫才们开发出各种奇技淫巧来补 JavaScript设计和历史遗留问题上的坑。
比如JavaScript中没有命名空间,而且只有function代码块内部可以隔离变量作用域,自调用匿名函数就用来防止变量弥散到全局,以免各种js库冲突。
- 因为JavaScript有很多致命缺陷,以致于各类淫才们开发出各种奇技淫巧来补 JavaScript设计和历史遗留问题上的坑。
ps记录一个题目:
14.以下代码输出什么? 写出作用域链查找过程伪代码
var a = 1;
function fn(){
console.log(a)//预解析的时候里面的a还是undefined
var a = 5
console.log(a)//a已经赋值 等于5
a++
var a //这时候a改变为6
fn3()//1
fn2()//6
console.log(a)//所以我等于20
function fn2(){
console.log(a)//我这里没有a,我找上一级,a等于6
a = 20//这时候我改变了fn里面的a 等于20
}
}
function fn3(){
console.log(a)//fn3里面没有声明,我去找上一级全局变量里的,等于1
a = 200//全局变量a变为200
}
fn()//undefined 1 6 20 200
console.log(a)//全局变量已经被fn3的a污染了,所以200
/*globalcontext={
AO:{
a:1 (a=20 -> a=200)
fn:function
fn3:function
}
scope:null
}
fn[[scope]]=globalcontext.AO
fn3[[scope]]=globalcontext.AO
fncontext={
AO:{
a:5 (-> a++ -> a=6)
fn2:function
}
scope:globalcontext.AO
}
fn3context={
AO:{}
scope:globalcontext.AO
}
fn2[[scope]]=fncontext.AO
fn2context={
AO:{}
scope:fncontext.AO
}
*/