zoukankan      html  css  js  c++  java
  • javascript 语句和严格模式(三)

    一、语句

    javascript程序由语句组成,语句遵守特定的语法规则。

    • block
    • break
    • continue
    • empty
    • if...else
    • switch
    • try catch
    • var
    • function
    • return
    • do...while
    • for
    • for...in
    • while
    • debugger
    • label
    • with

    1、block语句、var语句

    1.1 block语句

     块语句常用于组合0~多个语句。块语句用一对花括号定义。

    开发中,块语句通常和if for循环 while结合起来用。

    注意:

    在firefox控制台中输入{a:1,b:2},用作对象字面量时,会报语法错误,因为浏览器把它当成块处理了,如果想让浏览器理解为对象字面量,可以赋值给一个变量或者用括号括起来。

    注意:

    ES6前没有块级作用域。

    1.2声明语句

    正确声明方法:var a=1;

    坑:var a=b=1;

    正确的做法是:var a=1,b=1;

    2、try-catch语句

    执行try块中的语句。

    有异常执行catch。

    不管有没有异常,最后都会执行finally从句。

    javascript中的try...catch有3种形式:try...catch;try...finally;try...catch...finally。

    注意:try...catch嵌套

    如果内部的异常没有处理,抛给外面了,在外面处理之前,要先执行里面的finally语句。

    1、里面有个try...finally,外面有个try...catch,里面抛出异常。

    执行顺序,里面没有catch,所以会跳到最近的一层catch处理,也就是外层的catch处理,但是在跳出里面的block之前需要先执行finally。

    所以执行结果是:先"finally",然后是"outer oops"。

     2、里面有个try...catch...finally,外面有个try...catch,里面抛出异常。

    异常在内部处理过了,自然就不会再抛到外面再去处理。

    3、内部try...catch...finally

    内部catch中再抛出异常。

    此时,在finally执行后,又会输出“outer oops”。

    4、try...catch应用时注意【update20170306】

    一个try语句只会有一个捕获所有异常的catch代码块。如果你的处理手段取决于异常的类型,那么异常处理器必须检查异常对象的name属性来确定异常的类型。

    var add=function(a,b){
        if(typeof a!=='number'|| typeof b!=='number'){
            //throw抛出一个exception对象,该对象包含一个用来识别异常类型的name属性和一个描述性的message属性。
            throw{
                name:'TypeError',
                message:'add needs numbers'
            }
        }
        return a+b;
    }
    
    var try_it=function(){
        try{
            add("seven");
        }catch(e){
            document.writeln(e.name+': '+e.message);
        }
    }
    
    try_it();//TypeError: add needs numbers

    3、函数、switch、循环

    function语句用来定义函数对象。

    1、函数声明和函数表达式区别

    函数声明会被前置,所以在函数声明的代码前置调用也是可以正常执行的。

     

     还可以通过new Function构造器的方式去创建函数对象。

    2、for...in

     

    注意:

    1. for...in顺序不确定:具体顺序依赖于引擎的实现
    2. enumerable为false时不会出现
    3. for in的对象属性会受原型链的影响

    3、switch语句

     

    4、with语句

    with语句可以修改作用域

    直接x输出1,不用谢对象.x。

    在一层层访问很多层关系时,用with会比较方便。

    比如在浏览器里想查看form下所有元素时,用

    with(document.forms[0]){

        console.log(name.value);

    }//实际上就是隐式调用了document.forms[0].name.value。

    实际上这种深层次的访问,完全可以定义一个变量来代替,比如:

    var form=document.forms[0];
    console.log(form.name.value);

     不建议使用with,因为with会使javascript引擎优化变的更加难,因为在with里面作用域会变得复杂,在with里的每一个语句,每一个变量查询都有考虑到with后面的这个对象。总结:

    • 让JS引擎优化更难
    • 可读性差
    • 可被变量定义代替
    • 严格模式下被禁用

    二、严格模式

    严格模式是一种特殊的执行模式,它修复了部分语言上的不足,提供了更强的错误检查,并增强了安全性

    消除代码运行的一些不安全之处,保证代码运行的安全;

    提高编译器效率,增加运行速度;

    为未来新版本的Javascript做好铺垫。

    严格模式是向上兼容的,在用javascript写一些富应用,一些重的应用,或者是写一些node.js后端编程的时候,严格模式下的javascript执行对我们编写高质量、健壮性的代码非常有用。

    1、怎样进入严格模式

    向上兼容,比如老的IE,不支持严格模式,'use strict';会被当成普通字符串被忽略掉。

    1、函数内代码在严格模式下执行

    2、整个js文件内全部代码都在严格模式下执行。

    在整个js文件开头用'use strict'。

    小坑

    ‘use strict’;并不一定非要是第一行的代码。在'use strice';前面单引号引起来比如'abc';或者其他指令,这样也是可以的。

    如果写了其他的语句,比如var a;varb;这样就不可以了。

    2、严格模式和普通模式的区别

    •  with语句会报SyntaxError错
    • 未声明的变量被赋值会报ReferenceError错
    • arguments在严格模式下变为参数的静态副本,传入的参数与arguments无关系
    • delete参数函数名会报错
    • delete不可配置的属性也会报错
    • 对象字面量的重复属性名会报错
    • 禁止八进制字面量
    • eval,arguments变为关键字,不能作为变量、函数名
    • eval变成了独立作用域

    1、不允许用with

    一般模式输出1,严格模式报一个SyntaxError错误。

     解释一下!function(){}():

    解释器在解释一个语句时,如果以function开头,就会理解为函数声明。

    而前面加一个!可以让解释器理解为函数表达式,这样就可以立即调用了。

            !function(){
                with({x:1}){
                    console.log(x);
                }
            }();

    而省略了!的话:

            function(){
                with({x:1}){
                    console.log(x);
                }
            }();

    就会理解为函数声明,而函数声明没有名字会报错。

    2、不允许未声明的变量被赋值

    严格模式未声明的变量被赋值会报错ReferenceError。

     3、arguments变为参数的静态副本

     一般模式下:

    arguments和形参有绑定关系,修改了arguments[0]为100,a的值也被改成了100。

    !function (a){
                console.log(a); //a=1
                arguments[0]=100;
                console.log(a);//a=100
            }(1);   

    如果a的值不传,a就是undefined,这事修改了arguments[0]=100,a仍然是undefined,不会受arguments影响

    !function (a){
                arguments[0]=100;
                console.log(a);
            }();   //a=undefined

    严格模式:

    arguments变成的形参的静态副本,不管a传不传,都不会受argumetns影响。

    !function (a){
                'use strict';
                console.log(a); //a=1
                arguments[0]=100;
                console.log(a);//a=1
            }(1);   

    注意一点:

    虽然说严格模式下arguments和形参a是没有绑定关系的,如果传入了形参是对象,因为javascript中是共享传递的,所以修改了对象的属性,仍然会相互影响。

    4、delete参数、函数名报错

     一般模式:

    把一个参数delete,比如delete a,

    !function (a){
                //'use strict';
                console.log(a); //a=1
                console.log(delete a);
                console.log(a);//a=1
            }(1);   

    实际上这样做没有什么意义,会返回false,并且删除不成功,但是也不会报错。

    严格模式:

    严格模式下尝试去删除参数,或者函数名的话,会报语法错误:

    !function (a){
                'use strict';
                console.log(a); //a=1
                console.log(delete a);
                console.log(a);//a=1
            }(1);   

    5、delete不可配置的属性报错

    一般模式:

    删除configurable标签为false的属性,返回false并且删除失败。

    !function (a){
                //'use strict';
                var obj={};
                Object.defineProperty(obj,
                    'a',{configurable:false});
                console.log(delete obj.a); //flase
            }(1);   

    严格模式:

    试图删除configurable为false的属性时就会报TypeError。

    !function (a){
                'use strict';
                var obj={};
                Object.defineProperty(obj,
                    'a',{configurable:false});
                console.log(delete obj.a); //flase
            }(1);   

    6、对象字面量重复属性名报错

    一般模式:

    对象的属性字面量重复写属性也是合法的,并且属性以最后一个为准。所以下面obj.x为2。

    !function (){
                //'use strict';
                var obj={x:1,x:2};
                console.log(obj.x); //2
            }();   

    严格模式:

    严格模式下对象字面量重复属性名会报SyntaxError错。但是我在chrome55和firefox51下都没有报错。

    !function (){
                'use strict';
                var obj={x:1,x:2};
                console.log(obj.x); //2
            }();   

    7、禁止8进制的字面量

    一般模式:

    console.log(0123)会输出83。

    !function (){
                //'use strict';
                console.log(0123); //83
            }();   

    严格模式:

    !function (){
                'use strict';
                console.log(0123); //83
            }();   

    报错

    8、eval,arguments变为关键字,不能作为变量、函数名

    一般模式:

    !function (){
                //'use strict';
                function eval(){}
                console.log(eval); //function eval(){}
            }();  

    严格模式:

    !function (){
                'use strict';
                function eval(){}
                console.log(eval); 
            }();   

    9、严格模式下eval变成了独立作用域

    一般模式:

    eval中定义的变量在eval所在的函数内部仍然可以拿到变量。

    !function (){
                //'use strict';
                eval('var evalVar=2');
                console.log(evalVar);  //2
                console.log(typeof evalVar); //number
            }();   

    严格模式:

    在严格模式下,eval()中的代码会在一个独立的作用域中执行,所以就拿不到evalVar了。

    会报错

    !function (){
                'use strict';
                eval('var evalVar=2');
                console.log(evalVar);  
                console.log(typeof evalVar); 
            }();   

    10、在严格模式下,不能通过脚本访问arguments.callee

    11、禁止this关键字执向全局对象

    function f(){
        return !this;
      }
      // 返回false,因为"this"指向全局对象,"!this"就是false
    
      function f(){
        "use strict";
        return !this;
      }
      // 返回true,因为严格模式下,this的值为undefined,所以"!this"为true。

    因此,使用构造函数时,如果忘了加new,this不再指向全局对象,而是报错。

    function f(){
    
        "use strict";
    
        this.a = 1;
    
      };
    
      f();// 报错,this未定义

    参考:

    call by sharing——JavaScript中“共享传递”、“按值传递”、“按引用传递”

    http://blog.csdn.net/u012860063/article/details/52840275

    本文作者starof,因知识本身在变化,作者也在不断学习成长,文章内容也不定时更新,为避免误导读者,方便追根溯源,请诸位转载注明出处:http://www.cnblogs.com/starof/p/6371197.html有问题欢迎与我讨论,共同进步。

  • 相关阅读:
    十:audio 音频
    八: 操作提示(wxml 即将废弃)
    九: 操作提示(js版本)
    七: 表单标签(3)
    四: 基本标签
    五: 表单标签(1)
    六: 表单标签(2)
    webservice和wcf和web.api简单介绍
    Qt 中事件与处理
    Qt 事件过滤器
  • 原文地址:https://www.cnblogs.com/starof/p/6371197.html
Copyright © 2011-2022 走看看