我们先来看看下面的例子:
alert(a);//输出:function a(){ alert('我是函数') }
function a(){ alert('我是函数') }//
var a = '我是变量';
alert(a); //输出:'我是变量'
这代码等效于:
function a(){alert('我是函数')}
var a; //hoisting
alert(a); //输出:function a(){ alert('我是函数') }
a = '我是变量';//赋值
alert(a); //输出:'我是变量'
这短短的代码内里实在说清楚明了两个题目:
- function声明的优先级高于var声明:第一个alert输出能够看出
var a;
被function a(){}
掩盖掉了。 - 赋值优先于函数声明:第二个alert输出能够看出
a='我是变量'
又把function a(){}
掩盖掉了。
把一个变量添加到作用域中除有许多要领,以下:
- javascript言语预定义的,比如说this,arguments
-
formal parameter
(也就是中文说的形参吧) -
var
声明并赋值,比如说var a = 10;
-
var
声明不赋值,比如说var a;
-
function
声明,比如说function a(){};
我们来看看他们之间的优先级:
1.var声明并赋值
优先级高于function声明
这个上面已说了。
2.function声明
优先级高于formal parameter
function fnTest(a){
alert(a);
function a(){return "我优先"}
}
fnTest(100);//:function a(){return "我优先"}。能够看出function声明掩盖了`formal parameter`。
3.formal parameter
优先级高于预定义变量
function fnTest(arguments){
alert(arguments);
}
fnTest(100);//:100。申明`formal parameter`优先级比预定义的arguments高
对照以下:
function fnTest(a){
alert(arguments);
}
fnTest(100);//:[Object Arguments] {0:100,length:1}。当没有争执时输出就是预定义的arguments
4.formal parameter
优先级高于var声明不赋值
function fnTest(a){
alert(a);
var a;
}
fnTest(100);//:100。很明显,不多说
5.预定义变量
优先级高于 var声明不赋值
function fnTest(){
alert(arguments);
var arguments;
}
fnTest();//:[Object Arguments]。不是undefined,申明arguments没有被var声明掩盖
6.var声明不赋值
优先级高于函数外部作用域的其他一切声明
function fnTest(){
alert(fnTest);
var fnTest;
}
fnTest();//:undefined。
对照以下:
function fnTest(){ //
alert(fnTest); //
} //
fnTest(); //输出function fnTest(){alert(fnTest);}
这也恰好印证了作用域链查找变量的体式格局:在部分作用域里查找(若找到则返回,没必要往下继承查找) ==> 在上一级作用域里查找… ==> 直到全局作用域(若找不到则返回typeError)
末了看看下面的综合例子:
function fnTest(arguments){//
alert(arguments);//function arguments(){return "hello world"}
var arguments = 99;//
function arguments(){return "hello world"};
alert(arguments);//99
}
fnTest(100);