zoukankan      html  css  js  c++  java
  • javascript 严格模式

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

    一、如何使用严格模式?

    可以在js文件的最开头写入,这样就会在整个js文件中使用严格模式

    “use strict”;
    function func(){
    }  

    或者在一个函数的开头写入,这样会在这个函数内使用严格模式

    function func(){
      "use strict";  
    }
    

    二、严格模式与普通模式的区别

    1、严格模式下,不允许用with

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

    在严格模式下使用with会报一个SyntaxError 语法错误

    !function(){
    	"use strict";
      	with({x:1}){
            console.log(x);
        }  
    }();
    //SyntaxError: Strict mode code may not include a with statement
    

    2、严格模式下,不允许未声明的变量被赋值

    在普通模式下:

    !function(){
    	x=1;
    	console.log(window.x);//1
    }();
    

    没有使用var声明变量,而是直接给变量赋值,相当于声明了一个全局变量。

    在严格模式下:

    !function(){
    	"use strict";
    	x=1;
    	console.log(window.x);
    }();
    //Uncaught ReferenceError: x is not defined
    

    没有用var给变量声明而是直接赋值,会报一个ReferenceError错误  

      

    3、严格模式下,arguments变为参数的静态副本

    在普通模式下:

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

    定义了函数,并且传参,比如形参a和arguments[0]是有相互绑定关系的,如果修改了arguments[0]为100,那么对应的形参a也会被修改。需要注意的是,如果不给形参传值,比如这里的1不传,那么a的值是undefined,arguments[0]修改为100的话,a的值依然是undefined,不受arguments所影响。

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

    在严格模式下:

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

    arguments已经变成了参数的静态副本,不管参数有没有传值,都不会和arguments相互影响。

    但如果传入的参数是对象,修改对象的属性,仍然是会相互影响的。

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

      

    4、严格模式下,delect参数、函数名报错

    在普通模式下:

    !function(a){		
    	console.log(delete a);//false
    }(1);
    

    删除一个参数会返回false,删除不成功。

    在严格模式下:

    !function(a){
    	"use strict";		
    	delete a;
    }(1);
    //Uncaught SyntaxError: Delete of an unqualified identifier in strict mode.
    

    删除一个参数或函数名会报一个SyntaxError语法错误。

    5、严格模式下,delete不可配置的属性报错

    在普通模式下:

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

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

    在严格模式下:

    !function(a){
    	"use strict";
    	var obj={};
    	Object.defineProperty(obj,"a",{
    		configurable:false
    	});
    	delete obj.a;
    }(1);
    //Uncaught TypeError: Cannot delete property 'a' of #<Object>
    

    试图删除configurable为false 的属性的话,会报一个TypeError的错误。  

      

    6、严格模式下,重名错误

    (1)对象字面量重复属性名报错

    在普通模式下: 

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

    在严格模式下:

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

    网上说会报SyntaxError错误,本人测试严格模式下木有问题,不知道啥情况。

    (2)函数不能有重名的参数:

    !function(a,a,b){
        "use strict";
        return false;
    }();
    //Uncaught SyntaxError: Duplicate parameter name not allowed in this context

    正常模式下,如果函数有多个重名的参数,可以用arguments[i]读取。严格模式下,这属于语法错误。

      

    7、严格模式下,禁止八进制字面量 

    在普通模式下:

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

    普通模式下可以识别八进制数

    在严格模式下:

    !function() {
        'use strict';
        console.log(0123);//Uncaught SyntaxError: Octal literals are not allowed in strict mode.
    }();

    会报错,SyntaxError错误

      

    8、严格模式下,eval, arguments变为关键字,不能作为变量、函数名

    在普通模式下:

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

    在严格模式下:

    !function() {
        'use strict';
        function eval(){}//Uncaught SyntaxError: Unexpected eval or arguments in strict mode
    }();

    9、严格模式下,eval独立作用域

    在普通模式下:

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

    在严格模式下:

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

    在严格模式下,eval中的代码不能创建eval所在作用域下的变量、函数。而是为eval单独创建一个作用域,并在eval返回时丢弃。

    正常模式下,Javascript语言有两种变量作用域(scope):全局作用域和函数作用域。严格模式创设了第三种作用域:eval作用域。
    正常模式下,eval语句的作用域,取决于它处于全局作用域,还是处于函数作用域。严格模式下,eval语句本身就是一个作用域,不再能够生成全局变量了,它所生成的变量只能用于eval内部。

    10、严格模式下,禁止this关键字指向全局对象

    在普通模式下:

     !function f(){
        console.log(this);//window
        console.log(!this);//false
      }();

    返回false,因为"this"指向全局对象,"!this"就是false

    在严格模式下:

        !function f(){ 
        "use strict";
        console.log(this);//undefined
        console.log(!this);//true
      }();

     返回true,因为严格模式下,this的值为undefined,所以"!this"为true。

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

        function f(){
        "use strict";
        this.a = 1;//Uncaught TypeError: Cannot set property 'a' of undefined
      };
      f();// 报错,this未定义

    11、严格模式下,arguments.caller, arguments.callee被禁用

        function f1(){
        "use strict";
        f1.caller; // 报错
        f1.arguments; // 报错
      }
      f1();
    //Uncaught TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context.

    总结:

    不允许用with

    所有变量必须声明, 赋值给为声明的变量报错,而不是隐式创建全局变量。

    eval中的代码不能创建eval所在作用域下的变量、函数。而是为eval单独创建一个作用域,并在eval返回时丢弃。

    函数中得特殊对象arguments是静态副本,而不像非严格模式那样,修改arguments或修改参数变量会相互影响。

    删除configurable=false的属性时报错,而不是忽略

    禁止八进制字面量,如010 (八进制的8)

    eval, arguments变为关键字,不可作为变量名、函数名等

    一般函数调用时(不是对象的方法调用,也不使用apply/call/bind等修改this)this指向null,而不是全局对象。

    若使用apply/call,当传入null或undefined时,this将指向null或undefined,而不是全局对象。

    试图修改不可写属性(writable=false),在不可扩展的对象上添加属性时报TypeError,而不是忽略。

    arguments.caller, arguments.callee被禁用

  • 相关阅读:
    [LeetCode] 1474. Delete N Nodes After M Nodes of a Linked List
    [LeetCode] 1836. Remove Duplicates From an Unsorted Linked List
    [LeetCode] 1642. Furthest Building You Can Reach
    [LeetCode] 872. Leaf-Similar Trees
    [LeetCode] 1720. Decode XORed Array
    445. 两数相加 II
    83.删除链表中的重复元素
    笔试题常见的需要模板
    背包问题
    62.63 不同路径
  • 原文地址:https://www.cnblogs.com/aimee2004/p/5161285.html
Copyright © 2011-2022 走看看