var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar();//解释:js没有块级作用域,if switch while等不会有块级作用域
如果你对foo的值实际上为"10"而感到诧异的话,再看一下下面这个例子:
var a = 1; function b() { a = 10; return; function a() {} } b(); alert(a);发现浏览器会弹出alert(1)。//解释:第一点是函数声明的提升会把函数的实现都提升到作用域的最顶级,上面的函数b相当于
function b() {
function a() {}
a = 10; return; } 第二点是:这样的话,我们在b函数里面定义了一个a函数,a的作用域是在b函数的内部而非全局,这是对a的赋值相当于把a函数替换,作用域并不发生变化,相当于用var定义了一个a变量;所以在b函数外面输出a的时候只会去访问全局的a;
//var a = 1; function b() { a = 10; return; function a() {} } b(); alert(a);//报错a is undefined
另外:如果这里的a函数不是函数声明式定义的而是变量式定义的,变量提升而函数实现并不会提升:如下:
var a = 1; function b() { a = 10; return; a=function () {} //此处的a是全局的变量} b(); alert(a);//10
如果是这样的话
var a = 1; function b() {
a = 10; return;
var a=function () {} //此处的a是局部变量
} b(); alert(a);//1
等价于这个:
var a = 1; function b() {
var a;
a = 10; return;
a=function () {} //此处的a是局部变量
} b(); alert(a);//1
可以发现,声明语句中的赋值部分并没有被提升声明,只有名称被提升了。两种函数声明方式:
function test() { foo(); // TypeError "foo is not a function" bar(); // "this will run!" var foo = function () { // function expression assigned to local variable ‘foo‘ alert("this won‘t run!"); } function bar() { // function declaration, given the name ‘bar‘ alert("this will run!"); } } test();
这个例子中,只有包含函数体的函数声明会被提升声明。foo虽然会被提升声明,但是函数体却在执行中被赋值。以上就是提升声明时机的基本概念,看起来一点也不复杂。 Name resolution order(JavaScript中名称解析顺序) 名称解析顺序有4步,一般来说,如果一个名称已经被定义了,它就不会被另一个具有同名称的属性所覆盖。这也就意味着,函数声明会比变量声明优先。并不是名称的赋值操作不会被执行,只是说声明部分被忽略了而已。有些例外:
- 原生变量
arguments
特立独行,包含了传递到函数中的参数。如果自定义以arguments
为命名的参数,将会阻止原生arguments
对象的创建。所以勿使用arguments
为名称的参数。 - 胡乱使用
this
标识符会引起语法错误。 - 如果多个参数具有相同的命名,那么最后一个参数会优先于先前的,即时这个参数未定义。
Named Function Expressions(函数命名表达式) 你可以通过函数表达式给函数命名,语法上看起来像是函数声明,实则不是。上一段代码:
foo(); // TypeError "foo is not a function" bar(); // valid baz(); // TypeError "baz is not a function" spam(); // ReferenceError "spam is not defined" var foo = function () {}; // anonymous function expression (‘foo‘ gets hoisted) function bar() {}; // function declaration (‘bar‘ and the function body get hoisted) var baz = function spam() {}; // named function expression (only ‘baz‘ gets hoisted) foo(); // valid bar(); // valid baz(); // valid spam(); // ReferenceError "spam is not defined"
时间: 2024-10-07 20:58:43