前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >23严格模式

23严格模式

作者头像
Dreamy.TZK
发布2020-06-07 10:51:19
7640
发布2020-06-07 10:51:19
举报
文章被收录于专栏:小康的自留地小康的自留地

概述

严格模式是什么

严格模式是Javascript中的一种限制性更强的変种方式。严格模式不是一个子集:它在语义上与正常代码有着明显的差异。

不支持严格模式的刘览器与支持严格模式的浏览器行为上也不一样,所以不要在未经严格模式特性测试情况下使用严格模式。

严格模式可以与非严格模式共存,所以脚本可以逐渐的选择性加入严格模式。

严格模式的目的

首先,严格模式会将Javascript陷阱直接变成明显的错误。

其次,严格模式修正了一些引擎难以优化的错误:同样的代码有些时候严格模式会比非严格模式下更快

第三,严格模式禁用了一些有可能在未来版本中定义的语法。

开启严格模式

全局开启严格模式

只需要在全局写以下字符串即可。作用于全局作用域

代码语言:javascript
复制
"use strict";
a = 100;
console.log(a);

函数开启严格模式

在函数内写以下字符串即可。只作用于函数作用域。例如:

代码语言:javascript
复制
function fn() {
  "use strict";
  v = 200;
  console.log(v);
}

变量

禁止意外创建变量

  1. 非严格模式 在函数作用域中定义变量,不适用var关键字那么自动将其提升为全局变量。例如: function fn() { w = 200; console.log(w); //200 } fn(); console.log(w); //200
  2. 严格模式下 在严格模式下则会抛出异常 "use strict"; function fn() { // 在函数作用域中定义变量 - 不适用var关键字-> 自动将其提升为全局变量 w = 200; console.log(w); } fn(); console.log(w); // v = 100; // ^

静默失败转为异常

所谓静默失败就是既不报错也没有任何效果,例如改变常量的值。在严格模式下,静默失败会转换成抛出异常。

例如:

代码语言:javascript
复制
// 定义一个常量
const v = 3.14;

// 重新赋值
v = 1.14;
console.log(v);

以上代码在稍微老一点的浏览器可能并不会报错(新版报错),但开启严格模式后,一定会报错。

禁止delete关键字

在严格模式下不能对变量使用delete运算符。

例如:

代码语言:javascript
复制
var v = 100;

console.log(v); //100

delete v;
console.log(v); //100
  1. 严格模式下会抛出一个错误
  2. 非严格模式下会输出两个100

严格模式下禁用delete只针对删除变量,而不是数组元素和对象属性。

代码语言:javascript
复制
"use strict";
var arr = [0, 1, 2, 3, 4];
delete arr[0];
console.log(arr); //[ <1 empty item>, 1, 2, 3, 4 ]

var obj = {
  name: "张无忌",
};
delete obj.name;
console.log(obj.name); // undefined

对变量名的限制

在严格模式下,JavaScript对变量名也有限制。特别不能使用如下内容作为变量名:

  • implements
  • interface
  • let
  • package
  • private
  • protected
  • public
  • static
  • yield

上述关键词表示在ECMAScript的下一个版本中可能会用到他们,在严格模式下使用以上字符作为变量名会导致语法错误。

对象

不可删除的属性

代码语言:javascript
复制
"use strict";
delete Object.prototype;
console.log(Object.prototype);
// 报错

非严格模式下不会报错,但也不会删除成功。但在严格模式下会直接抛出错误。

但严格模式并不会限制所有对象,例如:

代码语言:javascript
复制
"use strict";
delete Math.random;
console.log(Math.random); //undefined
Math.random();

即使在严格模式下,还是可以删除Math.random方法。

属性名必须唯一

在严格模式下,一个对象内的所有属性名在对象内必须唯一。

代码语言:javascript
复制
"use strict";
var obj = {
  name: "张无忌",
  name: "周芷若",
};
console.log(obj.name); // 周芷若

开启严格模式后,如果对象具有相同属性,那么并不会报错,而是覆盖。

image-20200605175526975
image-20200605175526975

只读属性的赋值

代码语言:javascript
复制
"use strict";
var obj = {};
Object.defineProperty(obj, "age", {
  value: 18,
});
// 针对只读属性进行修改操作

obj.age = 80;
console.log(obj.age);

delete obj.age;
console.log(obj.age);

对于不可修改的属性,无论是修改还是删除都会发生报错。

不可扩展的对象

在严格模式下,不能为不可扩展的对象添加新属性。

代码语言:javascript
复制
"use strict";
var obj = {};
// 设置对象obj是一个不可扩展的对象
Object.preventExtensions(obj);

// 为对象obj新增属性或方法

obj.name = "张无忌";
console.log(obj);

以上代码在严格模式下会报错,非严格模式下不会报错。

函数

参数名必须唯一

在严格模式下,要求命名函数的参数必须唯一。

代码语言:javascript
复制
function fn(a, a, b) {
  console.log(a + a + b);
}
fn(1, 2, 3); //7

例如以上代码,非严格模式下会输出7,两个参数a都会被当作2;但在严格模式下,会抛出错误。

arguments的不同

在严格模式下, arguments对象的行为也有所不同。

  • 非严格模式下,修改命名参数的值也会反应到arguments对象中。
  • 严格模式下,命名参数与arguments对象是完全独立的。
代码语言:javascript
复制
"use strict";
function fn(value) {
  var value = "张无忌";
  console.log(value); // 张无忌
  console.log(arguments[0]); //严格模式下为周芷若 非严格模式下为周芷若
}
fn("周芷若");

非严格模式下arguments对象获取参数的值与形参有关。(如果局部变量与形参名相同,则根据就近原则获取);严格模式下arguments对象获取参数的值与形参无关。

arguments.callee()

在严格模式下,不能使用armaments对象的callee()方法。

代码语言:javascript
复制
"use strict";
function fn() {
  return arguments.callee;
}
fn();

以上代码在严格模式下会直接报错。

函数声明的限制

在严格模式下,只能在全局域和函数域中声明函数。

代码语言:javascript
复制
"use strict";
// 在全局作用域
function fn() {
  function n() {}
}

for (var i = 0; i < 10; i++) {
  // ECMAscript 6 新增 - 存在块级作用域
  var v = 100;
  // 开启严格模式后在块级不能定义函数
  function f() {
    console.log("this is function");
  }
}
console.log(v); // 100
f(); // ReferenceError: f is not defined

在严格模式下,函数的定义只能在全局作用域与函数作用域,不能在块级作用域

增加eval()作用域

在严格模式下,使用eval()函数创建的变量只能在eval()函数内部使用。

代码语言:javascript
复制
eval("var v = 100");
console.log(v);

以上代码在非严格模式下会输出100,而在严格模式下会抛出错误。

在严格模式下,会增加eval作用域。也就是说在eval函数定义的变量只能在当前eval函数使用。

arguments对象–禁止读写

在严格模式下,禁止使用eval()和arguments作为标示符,也不允许读写它们的值。

  • 使用var声明。
  • 赋予另一个值
  • 尝试修改包含的值。
  • 用作函数名。
  • 用作命名的函数的参数。
  • 在 try-catch语句中用作例外名。

以下语句在严格模式下均会报错:

代码语言:javascript
复制
eval = 17;

arguments++;

++eval;

var obj = {
  set p(arguments) {},
};

var eval;

try {
} catch (arguments) {}

function x(eval) {}

function (eval) { }

function arguments() { }

var y = function eval() { }

var f = new Function('arguments', "'use strict';return 17;")

抑制this

  • 在非严格模式下使用数的apyly()call()方法时,nullundefined值会被转换为全局对象。
  • 在严格模式下,函数的this值始终是指定的值(无论什么值)。
代码语言:javascript
复制
"use strict";
var v = 100;

function fn() {
  console.log(this.v);
}

var obj = {
  v: 200,
};
fn.call(null);

在严格模式下会抛出错误,必须明确指定this,例如fn.call(obj);

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-06-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
    • 严格模式是什么
      • 严格模式的目的
      • 开启严格模式
        • 全局开启严格模式
          • 函数开启严格模式
          • 变量
            • 禁止意外创建变量
              • 静默失败转为异常
                • 禁止delete关键字
                  • 对变量名的限制
                  • 对象
                    • 不可删除的属性
                      • 属性名必须唯一
                        • 只读属性的赋值
                          • 不可扩展的对象
                          • 函数
                            • 参数名必须唯一
                              • arguments的不同
                                • arguments.callee()
                                  • 函数声明的限制
                                  • 增加eval()作用域
                                  • arguments对象–禁止读写
                                  • 抑制this
                                  领券
                                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档