Javascript严格模式详解

原创 2018年04月16日 20:18:37

一、概述

1、什么是严格模式?

除了正常模式意外,ES5(2009年发布)还添加了一种模式,即“严格模式”。这种模式使javascript在更加严格的条件下运行。

2、为什么使用严格模式?

  • 消除javascript语言中一些不合理、不严谨之处,减少怪异现象;
  • 消除代码运行的一些不安全的地方,保证代码运行的安全;
  • 提高编译器效率,提高运行速度;
  • 为未来新版本的javascript打好基础;

3、怎么使用严格模式?
(1)针对整个脚本调用:

<script>
        "use strict";

</script>

"use strict" 放在所有可运行代码之前,则整个脚本将在“严格模式”下运行。

这个写法不利于函数合并,更好的方法:

 <script>
       (function(){
           "use strict";

       })();
 </script>

(2)针对单个函数:

function fn(){
"use strict";

}

"use strict"; 放在函数体所有可运行代码之前则整个函数体将在“严格模式”下运行。

二、严格模式和普通模式的区别:

1、全局变量必须显示声明

"use strict";
a=1;
console.log(a);//ReferenceError: a is not defined

2、静态绑定
javasript语言有一个特点,即允许动态绑定(某些属性和方法不是在编译时确定的,而是在运行时确定的)。
严格模式对动态绑定做出了一点限制。某些情况下,只允许静态绑定(属性和方法到底归属哪个对象,在编译阶段就应该确定)。优点:有利于编译效率的提高,也使代码更加容易阅读,更少出现意外。

(1)禁止使用with语句

"use strict";
var obj={
    name:'lwf',
    age:21
}
with(obj){//SyntaxError: Strict mode code may not include a with statement
    var name1=name;
    var age1=age;
}

另外,由于使用with语句会导致性能下降,同时也会给调试代码带来困难,因此开发过程中,不建议使用with。

(2) 创建eval作用域

正常模式下有两种作用域,即全局作用域和函数作用域,eval的作用域取决于其处于全局作用域和函数作用域。
严格模式下,会增加eval作用域。eval内生成的变量只能在eval中访问。
正常模式下:

var a=1;
var b=2;
eval("console.log(a)");//1
eval("var b=3;console.log(a)");//1
eval("console.log(b)");//3

严格模式下:

"use strict";
var a=1;
var b=2;
eval("console.log(a)");//1
eval("var b=3;console.log(a)");//1
eval("console.log(b)");//2

3、增强安全措施

(1)禁止this关键字指向全局变量

function f1(){
    console.log(!this);//false,正常模式下,this指向全局变量
}
f1();
function f2(){
    "use strict";
    console.log(!this);//true,严格模式下,this指向undefined,所以!this为true
}
f2();

(2)禁止在函数内部遍历调用栈

function f3(){
    console.log(f3.arguments);//{ '0': 1, '1': 2, '2': 3 }
}
f3(1,2,3);
function f4(){
    "use strict";
    console.log(f4.arguments);//TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context.
}
f4(1,2,3);

4、禁止删除变量

正常模式和严格模式下都禁止删除变量
正常模式:

var x=4
delete x;//删除变量会直接忽略
console.log(x);//4

删除变量:

"use strict";
var y=4;
delete y;//SyntaxError: Delete of an unqualified identifier in strict mode.
console.log(y);

5、显式报错
(1)正常模式下,对一个对象的只读属性赋值,不会报错,只会默默的失败;
严格模式下,将报错。
正常模式:

 var obj3={};
 Object.defineProperty(obj3,'name',{value:1,writable:false});
 obj3.name=2;
 console.log(obj3.name);//1,没有报错

严格模式:

"use strict";
var obj4={};
Object.defineProperty(obj4,'name',{value:1,writable:false});
obj4.name=2;//TypeError: Cannot assign to read only property 'name' of object '#<Object>'
console.log(obj4.name);

(2)正常模式下,对一个使用getter方法读取的属性进行赋值,不会报错,只会默默的失败;
严格模式下,会报错

var o={
    get v(){return 1}
}
console.log(o.v);//1
o.v=2;
console.log(o.v);//1
"use strict";
var o={
    get v(){return 1}
}
console.log(o.v);//1
o.v=2;//TypeError: Cannot set property v of #<Object> which has only a getter
console.log(o.v);

(3)正常模式下,对禁止扩展的对象添加属性,不会报错,只会默默失败;
严格模式下,会报错

var o={};
Object.preventExtensions(o);
o.v=1;
console.log(o.v);//undefined
"use strict";
var o={};
Object.preventExtensions(o);
o.v=1;//TypeError: Cannot add property v, object is not extensible
console.log(o.v);

6、重名错误
(1)函数不能有重名的参数
正常模式下,如果函数有重名参数,可以使用arguments[i]读取;
严格模式下,会报错。

function fn(a,a,b){
    console.log(arguments[0]);//1
    console.log(arguments[1]);//2
    return a;
}
console.log(fn(1,2,3));//2
"use strict";
function fn(a,a,b){//SyntaxError: Duplicate parameter name not allowed in this context
    console.log(arguments[0]);
    console.log(arguments[1]);
    return a;
}
console.log(fn(1,2,3));

7、禁止八进制表示法

var n=0100;
console.log(n);//64
"use strict";
var n=0100;//SyntaxError: Octal literals are not allowed in strict mode.
console.log(n);

8、arguments对象的限制
(1)不允许对arguments对象进行赋值

function fn1(){
console.log(arguments++);//NaN
}
fn1(1,2);
"use strict";
function fn1(){
console.log(arguments++);//SyntaxError: Unexpected eval or arguments in strict mode
}
fn1(1,2);
"use strict";
var obj = { set p(arguments) { } }; // 语法错误
try { } catch (arguments) { } // 语法错误
function arguments() { } // 语法错误
var f = new Function("arguments", "'use strict'; return 17;"); // 语法错误

(2)arguments不在追踪参数的变化

function fn1(a){
    a=2;
    console.log(arguments[0],a);//2,2
}
fn1(1);
 "use strict";
function fn1(a){
    a=2;
    console.log(arguments[0],a);//1 2
}
fn1(1);

(3)禁止使用arguments.callee
这意味着无法在匿名函数里面调用自身

function fn1(){
   console.log(arguments.callee);//[Function:fn1]
}
fn1();
"use strict";
function fn1(){
   console.log(arguments.callee);//TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
}
fn1();

9、函数声明必须在顶层
严格模式下,只允许在全局作用域或函数作用域的顶层声明函数。不允许在非函数的代码块中声明函数。

if(true){
    function fn(){
        console.log(1);
    }
}
fn();
"use strict";
if(true){
    function fn(){
        console.log(1);
    }
}
fn();//ReferenceError: fn is not defined

10、保留字
严格模式下新增了一些保留字:implements, interface, let, package, private, protected, public, static, yield
使用这些词作为变量名将报错。

function fn1(){
    var let=1;
    console.log(let);
}
fn1();//1
"use strict";
function fn1(){
    var let=1;//SyntaxError: Unexpected strict mode reserved word
    console.log(let);
}
fn1();

此外,ECMAscript第五版本身还规定了另一些保留字(class, enum, export, extends, import, super),以及各大浏览器自行增加的const保留字,也是不能作为变量名的。

参考:阮一峰的JavaScript严格模式详解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liwenfei123/article/details/79964424

Uncaught SyntaxError:Unexpected end of input

1、错误描述Uncaught SyntaxError:Unexpected end of input2、错误原因      由于编写jquery函数时缺少封闭括号“});”$(function(){3...
  • you23hai45
  • you23hai45
  • 2017-01-13 20:11:23
  • 2988

Mui+jsonp 跨域访问Uncaught SyntaxError: Unexpected token

mui jsonp uncaught syntaxerror:unexpected token;
  • l3922768721
  • l3922768721
  • 2017-09-26 14:37:07
  • 358

Javascript 严格模式详解

  • 2013年02月19日 14:49
  • 7KB
  • 下载

JavaScript中的严格模式

最近详细了解了下严格模式,本想自己总结下,但是我太懒了,就直接转一篇总结文吧! 如果不想要二手的,可以直接看https://developer.mozilla.org/en-US/docs/Web/...
  • u012422829
  • u012422829
  • 2016-09-05 21:45:47
  • 1513

Module build failed: SyntaxError: E:/wp+rc/try/src/index.js: Unexpected token

Module build failed: SyntaxError: E:/wp+rc/try/src/index.js: Unexpected token
  • u013558749
  • u013558749
  • 2016-07-18 11:36:27
  • 2730

Nutz 框架下 测试 jQuery-JSONP 插件跨域调用功能(Uncaught SyntaxError: Unexpected token : 出错原因解释)

注:本文欢迎转载,以下为本人亲测,转载请注明:http://blog.csdn.net/wqmain/article/details/8905287 插件介绍:众所周知,使用ajax直接发起请求...
  • wqmain
  • wqmain
  • 2013-05-10 14:07:27
  • 25560

JavaScript严格模式与非严格模式之间的区别

严格模式 非严格模式 禁止使用with语句 允许使用with语句 所有变量要先声明 使用未声明的变量将隐式声明为全局变量 函数(非方法)中的this是und...
  • weixin_37986839
  • weixin_37986839
  • 2017-08-30 00:45:00
  • 301

Js中严格模式和非严格模式的区别

严格模式和非严格模式的区别 //f1.js 'use strice'; //整个js文件都是严格模式下执行的 var n = 1; var foo = function(){...}; //....
  • Ayiayi00
  • Ayiayi00
  • 2017-09-02 18:17:01
  • 1651

ajaxFileUpload插件上传文件 返回 syntaxError :unexpected token <

Html代码   table id="deploy_application" class="bordered-table">    tr>      td id="application...
  • han_dongwei
  • han_dongwei
  • 2013-01-11 18:47:11
  • 40888

(一)Unity5.0新特性------转载自官方-unity5.0正式发布了,看看带来哪些重要的新特性!

Unity 5.0Unity 5.0 is our biggest and boldest release ever. Powerful new features in Unity 5 include...
  • u010019717
  • u010019717
  • 2015-03-04 11:26:45
  • 38675
收藏助手
不良信息举报
您举报文章:Javascript严格模式详解
举报原因:
原因补充:

(最多只允许输入30个字)