关于JavaScript严格模式的一些笔记

严格模式是什么?

js的严格模式,即ES5中引入一种代码执行方式的变体,与js的非严格模式相比,它:

  • 修正了该语言的一些重要缺陷,消除了一些不严谨的地方
  • 清除了一些代码运行的不安全之处,增强了安全机制
  • 提高了代码的运行速度
  • 禁用了一些未来可能会定义的语法,为以后的版本做准备

支持严格模式的浏览器:
    Internet Explorer 10 +、 Firefox 4+ Chrome 13+、 Safari 5.1+、 Opera 12+。


严格模式的开启方式

<script>
	"use strict"
	myName = "旦旦boom";
	console.log(myName);//报错:myName is not defined
	//在脚本中使用严格模式
</script>
<script>
	function fn(){
		"use strict"
		myName = "旦旦boom";
		console.log(myName);
	}
	fn();//报错:myName is not defined
	//在函数中使用严格模式
</script>

如上,在需要进入严格模式的脚本或函数的开头处,码入“use strict”指令,即可在对应代码块进入严格模式。

ps:
    “use strict”(可以使用单引号也可以使用双引号)指令不包含任何语言的关键字,仅仅是一个包含一个特殊字符串直接量的表达式。
    对于没有实现ES5的js解释器来说,这只是一条什么也没做、没有副作用的表达式关键句。


严格模式与非严格模式的区别

  • 严格模式中所有的变量都要事先声明;非严格模式中,不声明直接使用变量,会给全局对象添加新属性
<script>
	nName = "非严格";
	console.log(nName);//非严格
	(function(){
	    "use strict"
	    sName = "严格";
	    console.log(sName);//Uncaught ReferenceError: sName is not defined
	})();
</script>
  • 严格模式中,函数声明时,形参重名会产生语法错误;非严格模式中,最后一个重名的形参会覆盖前面所有重名的形参
<script>
    function nFn(a,b,b){
        console.log(a);
        console.log(b);
        console.log(b);
    }
    nFn(1,2,3);//1,3,3
    nFn(1,2);//1,undefined,undefined
    (function(){
        "use strict"
        function sFn(a,b,b){
            console.log(a);
            console.log(b);
            console.log(b);
        }//Uncaught SyntaxError: Duplicate parameter name not allowed in this context
    })();
</script>
  • 严格模式中,函数里的arguments拥有传入实参的静态副本;非严格模式中,arguments的元素和函数参数指向同一个值的引用
<script>
    function nFn(a){
        a = 10;
        console.log(a);
        console.log(arguments[0]);
    }
    nFn(4);//10  10
    (function(){
        "use strict"
        function sFn(a){
            a = 10;
            console.log(a);
            console.log(arguments[0]);
        }
        sFn(4);//10  4
    })();
</script>
  • 严格模式限制了调用栈的检测能力,使用arguments.callee.caller和arguments.callee时会报错
<script>
    function nFn(){
        console.log(arguments.callee === nFn);
        console.log(arguments.callee.caller);
    }
    nFn();//true null
    (function(){
        "use strict"
        function sFn(){
            console.log(arguments.callee === sFn);
            console.log(arguments.callee.caller);
        }
        sFn();//Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them  
    })();
</script>
  • 严格模式中不允许使用with语句
<script>
    var nObj = {
        name:"旦旦boom",
        age:18
    }
    with(nObj){
        console.log(name);//旦旦boom
        console.log(age);//18
    }
</script>
<script>
    "use strict"
    var sObj = {
        name:"旦旦boom",
        age:18
    }
    with(sObj){//Uncaught SyntaxError: Strict mode code may not include a with statement
        console.log(name);
        console.log(age);
    }
</script>
  • 严格模式中不允许使用eval和arguments作为变量名
<script>
    var eval = 0;
    var arguments = 0;
    //一切正常
</script>
<script>
	"use strict";
    var eval = 0;//Uncaught SyntaxError: Unexpected eval or arguments in strict mode
    var arguments = 0;
</script>
  • 严格模式中不允许使用以0为前缀的八进制
<script>
	console.log(010);//8
</script>
<script>
	"use sitrict";
	console.log(010);//Uncaught SyntaxError: Unexpected eval or arguments in strict mode
</script>
<script>
	"use sitrict";
	console.log(parseInt(10,8));//8
</script>
  • 严格模式中,函数内部没有明确隶属对象的this为undefined;非严格模式中,这种this指向window
<script>
    function nFn(){
        console.log(this);
    }
    nFn();//window
    (function(){
        "use strict"
        function sFn(){
            console.log(this);
        }
        sFn();//undefined;
    })();
</script>
  • 严格模式中,给只读属性赋值、给不可拓展的对象创建新成员,都会报错;非严格模式则什么都不做
<script>
    var person = new Object();
    Object.defineProperty(person , "name" , {value:"旦旦boom", writable:false});//{name: "旦旦boom"}
    Object.seal(person);
    person.name = "旦旦";//什么都没做
    person.age = 18;//什么都没做
    console.log(person);//{name: "旦旦boom"}
    (function(){
        "use strict"
        person.name = "旦旦";//Uncaught TypeError: Cannot assign to read only property 'name' of object '#<Object>'
        person.age = 18;//Uncaught TypeError: Cannot add property age, object is not extensible
    })();
</script>
  • 严格模式中,传入eval()中的代码不能在调用程序所在的上下文中声明变量或定义函数,即eval()外部不能访问eval()内部声明的变量和定义的函数。另外,传入eval()的代码遵循严格模式执行。
<script>
    eval("var nName = '旦旦boom'; console.log(nName);");//旦旦boom
    console.log(nName);//旦旦boom
    (function(){
        "use strict"
        eval("var sName = '旦旦boom'; console.log(sName);")//旦旦boom
        console.log(sName);//Uncaught ReferenceError: sName is not defined
    })();
</script>
  • 严格模式中,若delete运算符后跟随变量、函数、函数参数等非法标识符,或跟随一个不可配置的属性,则报错;非严格模式中,delete后跟随非法标识符或不可配置的属性,则什么都不做,并返回false
<script>
    var person = new Object({
        name : "旦旦boom",
        age : 18
    });
    delete person;//什么都不做
    delete Object.prototype;//什么都不做
    (function(){
        "use strict"
        delete person;//Uncaught SyntaxError: Delete of an unqualified identifier in strict mode.
        delete Object.prototype;//Uncaught TypeError: Cannot delete property 'prototype' of function Object() { [native code] }
    })();
</script>
  • 严格模式中,通过call()或apply()来调用函数时,传入的第一个值不会被转换;非严格模式中,call()和apply()传入的第一个值如果是null和undefined,则会被全局对象取代,如果是原始值则转换为对应的包装对象
<script>
    var nObj = {
        fn : function(){
            return this;
        }
    };
    console.log(nObj.fn.call(undefined));//window
    console.log(nObj.fn.apply(null));//window
    (function(){
        "use strict"
        var sObj = {
            fn : function(){
                return this;
            }
        };
        console.log(sObj.fn.call(undefined));//undefined
        console.log(sObj.fn.apply(null));//null
    })();
</script>

以上,
如有错误,欢迎指正_(:τ」∠)_

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值