当前位置: 首页 > 科技观察

前端开发必须知道JavaScript中的严格模式

时间:2023-03-16 11:24:14 科技观察

一、概述除了正常的运行模式,ECMAscript5还增加了第二种运行模式:“严格模式”。顾名思义,这种模式让JavaScript在更严格的条件下运行。1、设置“严格模式”的目的主要有以下几点:2、剔除Javascript语法中一些不合理、不严谨的部分,减少一些怪异的行为;3.剔除部分代码运行不安全的部分,保证代码安全运行;4.提高编译效率,提高运行速度;5.为以后的Javascript新版本铺路。“严格模式”体现了Javascript更合理、更安全、更严谨的发展方向。包括IE10在内的主流浏览器都已经支持了,很多大型项目也开始全面拥抱它。另一方面,同样的代码在“严格模式”下可能会有不同的运行结果;一些可以在“正常模式”下运行的语句将不能在“严格模式”下运行。掌握这些内容,将有助于你更详细、更深入地理解Javascript,使你成为更好的程序员。本文将详细介绍“严格模式”。2.输入标志进入“严格模式”的标志是下面一行:“usestrict”;旧版本的浏览器会把它当成一行普通的字符串而忽略。3、如何调用“严格模式”有两种调用方式,适用于不同的场合。1、对于整个脚本文件,在脚本文件的第一行加上“usestrict”,整个脚本就会以“严格模式”运行。如果这行语句不在第一行,则无效,整个脚本以“正常模式”运行。如果将不同模式的代码文件合并到一个文件中,这一点需要特别注意。上面的代码表示一个网页中有两段Javascript代码依次出现,前者是严格模式,后者不是严格模式。2.对于单个函数,把"usefunctionbody**行的*中的“strict”,整个函数运行在“strictmode”。functionstrict(){“usestrict”;return”这是严格模式。";}functionnotStrict(){return"这是正常模式。";}3.脚本文件的另类写法由于第一种调用方式不利于文件合并,所以最好借用第二种方式,将整个脚本文件放在一个匿名函数中,立即执行。(function(){"usestrict";//somecodehere})();4.语法和行为的改变严格模式对Javascript的语法和行为做了一些改变。1.全局变量在普通模式下是显式声明的,如果一个变量在没有声明的情况下被赋值,默认为全局变量,严格模式禁止这种用法,必须显式声明全局变量"usestrict";v=1;//错误,v未声明for(i=0;i<2;i++){//报错,iisnotdeclared}因此,在严格模式下,变量必须先用var命令声明,然后再使用。2.静态绑定Javascript语言的一个特性是允许“动态绑定”,也就是说,某些属性和方法属于哪个对象不是在编译时确定的,而是在r不合时宜。严格模式不允许动态绑定,只允许静态绑定。也就是说,属性和方法属于哪个对象,必须在编译阶段就确定下来。这样有利于提高编译效率,也让代码更易读,更不容易出现意外。具体涉及以下几个方面。(1)禁止使用with语句因为with语句在编译时无法确定该属性属于哪个对象。"usestrict";varv=1;with(o){/grammarerrorv=2;}(2)在普通模式下创建eval作用域,Javascript语言有两种变量作用域(scope):全局作用域和函数作用域。严格模式创建第三个范围:eval范围。在普通模式下,eval语句的作用域取决于它是在全局作用域还是函数作用域。在严格模式下,eval语句本身就是一个作用域,不能再生成全局变量。它生成的变量只能在eval内部使用。"usestrict";varx=2;console.info(eval("varx=5;x"));//5console.info(x);//23.增强安全措施(1)禁止this关键字指向全局对象functionf(){return!this;}//返回false,因为“this”指向全局对象,“!this”为falsefunctionf(){"usestrict";return!this;}//返回true,因为在严格模式下,this的值是未定义的,所以"!this"为true。因此,在使用构造函数时,如果忘记添加new,this不再指向全局对象,而是报错。functionf(){"usestrict";this.a=1;};f();//报错,this未定义(2)函数内部禁止遍历调用栈functionf1(){"usestrict";f1.caller;//报错f1.arguments;//报错}f1();4.禁止删除变量严格模式下不能删除变量。只能删除将configurable设置为true的对象属性。"usestrict";varx;deletex;//语法错误varo=Object.create(null,'x',{value:1,configurable:true});deleteo.x;//删除成功5.显式错误正常模式下在这种情况下,为对象的只读属性赋值不会报告错误,而只会静默失败。在严格模式下,会报错。"usestrict";varo={};Object.defineProperty(o,"v",{value:1,writable:false});o.v=2;//在报错的严格模式下,使用getter方法读取给一个属性赋值,会报错。"usestrict";varo={getv(){return1;}};o.v=2;//在报错的严格模式下,如果给禁止扩展的对象添加新的属性,就会报错。"usestrict";varo={};Object.preventExtensions(o);o=1;//严格报错模式下,删除不可删除的属性,会报错。"usestrict";deleteObject.prototype;//错误6.重复名称错误严格模式增加了一些语法错误。(1)对象不能有同名属性在普通模式下,如果一个对象有多个同名属性,最后赋值的属性将覆盖之前的值。在严格模式下,这是一个语法错误。"usestrict";varo={p:1,p:2};//语法错误(2)函数不能有同名参数在普通模式下,如果函数有多个同名参数,可以使用arguments[i]阅读。在严格模式下,这是一个语法错误。"usestrict";functionf(a,a,b){//语法错误返回;}7.禁止八进制表示法在普通模式下,如果一个整数的第一位是0,则表示这是一个八进制数,例如0100等于十进制数64。严格模式禁止这种表示法,如果***位整数为0,会报错。"usestrict";varn=0100;//语法错误8.arguments对象的限制Arguments是函数的参数对象,严格模式限制了它的使用。(1)不允许将“usestrict”赋值给参数;arguments++;//语法错误varobj={setp(arguments){}};//语法错误try{}catch(arguments){}//语法错误functionarguments(){}//语法错误varf=newFunction("arguments","'usestrict';return17;");//语法错误(2)arguments不再跟踪参数变化functionf(a){a=2;return[a,arguments[0]];}f(1);//普通模式为[2,2]functionf(a){"usestrict";a=2;return[a,arguments[0]];}f(1);//严格模式为[2,1](3)禁止使用arguments.callee,这意味着你不能在匿名函数中调用自己。"usestrict";varf=function(){returnarguments.callee;};f();//错误9.函数必须声明,以后新版Javascript会在顶层引入“块级作用域”.为了与新版本保持一致,严格模式只允许在全局范围或函数范围的顶层声明函数。也就是说,不允许在非函数代码块内声明函数。"usestrict";if(true){functionf(){}//语法错误,}for(vari=0;i<5;i++){functionf2(){}//语法错误}10.保留字备查在新版Javascript的过渡中,严格模式增加了一些保留字:implements、interface、let、package、private、protected、public、static、yield。使用这些词作为变量名会引发错误。functionpackage(protected){//语法错误"usestrict";varimplements;//语法错误}另外ECMAscript第五版本身也规定了其他的保留字:class,enum,export,extends,import,super。它们也无法使用。【本文为专栏作家“谢军”原创稿件。转载可通过作者微信取得联系公众号(jingfeng18)】点此查看该作者更多好文