• JavaScript中需要注意的几个问题


                                                         JavaScript中需要注意的几个问题

    JavaScript是一门弱语言,她使用起来不像C/C++那样有十分繁琐的内存管理、类型定义等,所以学习JavaScript的门槛相对来说也比较低。门槛低并不意味着这门语言很简单,我们在使用的时候会遇到各种千奇百怪的问题,有些是因为浏览器的兼容性引起的,有些是因为JS语法本身所引起的,还有些是因为ECMAScript标准的改变而引起的,总之,这样的问题很多,下面列举

    几个比较容易忽略的点

      1. switch的case判断

    var t = event.keyCode;
    switch (t) {
       case '65':
          alert("Yay!");
          break;
    }

      当keycode为65时,你会发现,咦?怎么木有alert! 这里需要明确的是,switch在判断的时候使用的是全等号“===”,全等号在比较的时候首先看数据类型是不是一样的,而在这里,t是Number类型,而'65'是String。

      2. 严格模式下this≠window

    "use strict";
    var global = (function() {
        console.log(this); //undefined
    })();

      有时候我们需要用global来缓存this这个全局环境(可能是window,也可能是其他的,比如在Worker中没有window对象,用self代表Global),但是在严格模式下函数作用域返回的this为undefined,一般,我们可以采用如下方式获取到Global对象:

    "use strict";
    var global = (function() {
        var t = new Function("return this")();
        console.log(t);
    })();

    或者:

    "use strict";
    var global = (function() {
        var t = window.eval("this");
        console.log(t);
    })();

      因为new Function是在全局作用域上执行的,所以返回的是Global对象,下面的eval需要一起注意,eval前如果不交window,那它便处于function作用域中(javascript利用function里分隔作用域),自然不会返回window或者全局对象。使用Function要注意一点:

    (function () {
       var local = 1;
       new Function("console.log(typeof local);")(); // logs undefined
    }());

      new Function工作在Global作用域链下,所以是访问不到匿名函数中local的~

      3. 变量提升(Hoisting)

    var t = "global";
    function foo(){
        console.log(t); //undefined
        return; 
       var t = "local"; }

      这是一个老生常谈的问题,var最好不好到处散布。所谓的变量提升,在这里存在两个作用域,一个是Global作用域,他下面有t和foo这两个变量,而foo指向的是foo作用域,foo作用域下有一个t变量,画个图演示下吧

    [Global Scope]
        |----- t   [String] undefined -> "global"
        |----- foo [Reference] [foo Scope]
    
    [foo Scope]
        |----- t   [String] undefined -> "local"

      刚进入全局作用域链的时候,程序扫描到t和foo两个变量,于是给这个t赋值为undefined,扫面完了之后,看到t有值,于是给赋值”global“,foo指向[foo Scope],于是进入[foo Scope],继续扫描函数作用域链下的变量,发现目标t之后,赋值为undefined,在console.log时,是这样的:

    var t = "global";
    function foo(){
        var t; // 等同于 -> var t = undefined;
        console.log(t); //undefined 
    return;  
    var t = "local";
    }

      上面的例子写不写return结果都是一样的,加return,只是为了更好的表达变量提升这个动作的存在。一般比较推荐的变量定义方式:

    function foo(a, b, c) {
        var x = 1,
            bar,
            baz = "something";
    }

      一个var,后边连着一串变量的定义。

    附:javascript严格模式下要注意的地方(转自次碳酸钴

     1. 变量必须声明才能使用

    "use strict";
    a=1; //缺少var语句做声明,因此报错
    "use strict";
    var a=b=1; //错误 b未声明

     2. 函数声明语句(不包括表达式)不允许在普通代码块(不包括闭包)中使用

    "use strict";
    (function(){
      //闭包中是允许使用函数声明语句的
      function func(){};
    })();
    {
      var f=function(){}; //函数声明表达式允许
      function func(){}; //函数声明语句在普通闭包中,错误
    };

    3. 闭包内的this不指向Global对象

    "use strict";
    (function(){
      alert(this); //输出undefined
    })();

    4. 对象属性和函数形参不能重复声明

    "use strict";
    var o={a:1,a:1};
    //这个对象定义了两个a属性,因此报错
    "use strict";
    function func(a,a){};
    //这个函数的两个形参都是a,因此报错

    5. eval拥有类似闭包的作用域

    "use strict";
    var a=1,b=1;
    eval("var a=2");
    window.eval("var b=2");
    alert(a); //输出1 因为运行的a变成了eval作用域的局部变量
    alert(b); //输出2 window.eval依然是全局作用域

    6. callee和caller属性无法使用

    "use strict";
    function func(){
      return arguments.callee; //错误 callee无法使用
    };
    func();

    7. with语句无法使用

    "use strict";
    with({});

    8. 八进制数字常量无法使用

    "use strict";
    var a=0999; //十进制,可以使用
    var b=0123; //八禁止,无法使用

    9. 普通模式下的一些无效操作变成错误

    "use strict";
    var a=1;
    delete a;
    //错误 无法删除var声明的变量
    "use strict";
    var o={get a(){}};
    o.a=1;
    //错误 给只读属性赋值

    简单总结这么多,推荐“次碳酸钴”童鞋的博客,细致入微、内容深刻,博客入口:http://www.web-tinker.com

    关于JavaScript strict mode的详细介绍,请移步:MDN Strict_mode

  • 相关阅读:
    UVA 1025 A Spy in the Metro DP水题
    ZOJ 3814 Sawtooth Puzzle BFS
    ZOJ 3816 Generalized Palindromic Number
    UVA 10859 Placing Lampposts 树形DP
    UVA 11825 Hackers' Crackdown 状压DP
    POJ 2887 Big String 线段树 离线处理
    POJ 1635 Subway tree systems Hash法判断有根树是否同构
    BZOJ 3110 k大数查询 & 树套树
    sdoi 2009 & 状态压缩
    来自于2016.2.24的flag
  • 原文地址:https://www.cnblogs.com/lizonghai/p/4639753.html
Copyright © 2020-2023  润新知