Django开发者群  - 讨论区

标题:Javascript中同名标识符优先级

2010年11月22日 星期一 13:10

一,局部变量先使用后声明,不影响外部同名变量Js代码 [url=#] [/url]
! H- ?% ~+ |+ ?6 g, [6 C

  • var x = 1; // --> 外部变量x

  • function fn(){
  •     alert(x);  // --> undefined 局部变量x先使用
  • & H, @8 W# @0 Z
    var x = 2; // 后声明且赋值
  • }
  • fn();
  • alert(x); // --> 1

var x = 1; // --> 外部变量xfunction fn(){        alert(x);  // --> undefined 局部变量x先使用        var x = 2; // 后声明且赋值}fn();alert(x); // --> 1
第一点,函数fn内第一句输出x,x是在第二句才定义的。这在js中是允许的,这里的允许是指不会出现语法错误程序可以运行。 3 l# U6 v8 ~; e4 {' ~& Q. z* j, {
但在其它语言如C,Java中却是不允许的。变量必选先声明后使用,如: " y, e6 ~% H# U/ b0 s. Q4 a
Java代码 [url=#] [/url]
5 b3 h- t: Z( U0 G8 O
  • public - k  H" ]$ g' G* x+ F( l! G6 S% W
    class Test {
  • : V8 g) ]- h# u& E9 L- ]  H1 V+ e
    public " L' o" }6 {2 x" ?) m1 X
    static
    void main(String[] args) {
  •         System.out.println(x); // 先使用
  • 4 [& D+ ]% Y1 d
    int x = 10; // 后声明
  •     }
  • }

public class Test {        public static void main(String[] args) {                System.out.println(x); // 先使用                int x = 10; // 后声明        }}
Java中编译器会提示错误,程序无法运行。

第二点,函数fn内的局部变量x不会影响到外部的变量x。即fn内alert输出不是1,而是undefined。

顺便提下,这段代码经常出现在前端面试题中。
/ T( j# \4 q8 I7 c+ a6 \" _" ^
% U& {2 h' H4 A% r  Z
二,形参优先级高于函数名Js代码 [url=#] [/url] 5 P: L& v* C: U6 b* j+ h, X- `

  • function fn(fn){
  •     alert(fn);
  • }
  • fn('hello'); // --> "hello"
5 g/ }/ f. Z# O, ~4 m2 b- ]
function fn(fn){        alert(fn);}fn('hello'); // --> "hello" / u- [- Q2 }* U. o" w* ?
可以看到函数名和形参同名都是fn,输出的是字符串"hello",却不是函数fn的函数体(fn.toString())。 ; n2 Y; ^& P  R  q, ~; {2 x5 A
7 P+ r% G2 d6 u9 }) n# ^/ G

三,形参优先级高于argumentsJs代码 [url=#] [/url]
& M8 P5 J1 P& V$ e7 G
  • function fn(arguments){
  •     alert(arguments);
  • }
  • fn('hello'); // --> "hello"

function fn(arguments){        alert(arguments);}fn('hello'); // --> "hello" $ I3 g; t4 m, ]. x
arguments对象可以直接在函数内使用,是语言本身提供的标识符。
这里刚好将形参声明成与其同名。输出可以看到是"hello"而非"[object Object]",即形参arguments覆盖了语言本身提供的真正的arguments。

0 D+ {) ^6 n" R) n+ f
四,形参优先级高于只声明却未赋值的局部变量Js代码 [url=#] [/url] 3 G- N% o" _* d3 x3 ~0 t& s  D
. ~/ s- l- Z: E! t8 V: N, i  i
  • function fn(a){

  • var a;
  •     alert(a);
  • }
  • fn('hello'); // --> "hello"

function fn(a){        var a;        alert(a);}fn('hello'); // --> "hello" 2 i. _- @' b/ U( l' N4 X! }
函数fn形参为a,函数内第一句仅声明局部变量a,却并未赋值。从输出结果是"hello"而非undefined可以看出形参a优先级高于仅声明却未赋值的局部变量a。 " p! C) ^5 n# K0 ~7 S! c' e$ M, J
7 m3 M* L$ ~* W$ r5 t7 ?/ \5 ?2 E
! h8 C/ H3 e6 z
五,声明且赋值的局部变量优先级高于形参Js代码 [url=#] [/url]

  • function fn(a){
  • * s0 P( [8 |+ l
    var a = 1;
  •     alert(a);
  • }
  • fn('hello'); // --> "1"

function fn(a){        var a = 1;        alert(a);}fn('hello'); // --> "1" " B/ `6 S2 M5 H+ G( \- ~
函数fn形参为a,函数内第一句仅声明局部变量a,赋值为1。从输出结果是"1"而非"hello"可以看出声明且赋值的局部变量a优先级高于形参a。

7 d! k2 j6 `% A+ H
六,形参赋值给同名局部变量时Js代码 [url=#] [/url]
9 a. s0 W; I- b. ^
  • function fn(a){

  • var a = a;
  •     alert(a);
  • }
  • fn('hello');

function fn(a){        var a = a;        alert(a);}fn('hello');
暂不运行,猜测下结果。如果按照第五点:声明且赋值的局部变量优先级高于形参。那么a将是undefined。但实际上a是"hello",即右a是形参a,左a才是局部变量a。 $ q! |% ^/ U7 q* r
: U+ a5 f7 ?3 c
1 o# n, m6 G' e0 |. ]
! D+ U3 J' H9 C8 f0 `( ~
( |& N) Z' O, c+ y; Z7 \
这里的两个a互不干扰,谁也没覆盖谁。这与刚刚说的赋值的局部变量优先级高于形参又矛盾了。但引擎这样做的确是我们想要的,因为并不希望var a = a后a是undefined.

如下红色区域有误,请重新填写。

    你的回复:

    请 登录 后回复。还没有在Zeuux哲思注册吗?现在 注册 !

    Zeuux © 2024

    京ICP备05028076号