Ref: Javascript 严格模式详解

使得Javascript在更严格的条件下运行:

  - 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;

  - 消除代码运行的一些不安全之处,保证代码运行的安全;

  - 提高编译器效率,增加运行速度;

  - 为未来新版本的Javascript做好铺垫。

(1) 需要在有效运行代码的第一行。

  <script>
    "use strict";
    console.log("这是严格模式。");
  </script>   <script> // 这个不是严格模式
    console.log("这是正常模式。");kly, it's almost 2 years ago now. I can admit it now - I run it on my school's network that has about 50 computers.
  </script>

(2) 针对单个函数

  function strict(){
    "use strict";
    return "这是严格模式。";
  }   function notStrict() {
    return "这是正常模式。";
  }

(3) 将整个脚本文件放在一个立即执行的匿名函数之中,利于文件合并

  (function (){
    "use strict";
    // some code here
   })();

全局变量显式声明

【没啥可说的】

静态绑定

严格模式对动态绑定做了一些限制。

某些情况下,只允许静态绑定。

(1)禁止使用with语句

  • with带来的一点点好处

Ref: Javascript中的with关键字

为了简化多次编写访问同一对象的工作,比如下面的例子:

var qs = location.search.substring(1);
var hostName = location.hostname;
var url = location.href; ------------------------------------------------
with (location){  // 设置代码在特定对象(location)中的作用域
var qs = search.substring(1);
var hostName = hostname;
var url = href;
}
  • with带来的潜在问题

- 性能问题

- 语义不明,难以调试

function foo(obj) {
with (obj) {
a = 2; // 这里的a需要看obj的脸色
}
}

(2)创设eval作用域 

Javascript语言有两种变量作用域(scope):全局作用域和函数作用域。严格模式多了一个第三种作用域:eval作用域。

"use strict";

var x = 2;
console.info(eval("var x = 5; x")); //
console.info(x); //

增强的安全措施

(1)禁止this关键字指向全局对象

Ref: Javascript的this用法

函数运行时,自动生成的一个内部对象。

情况一:纯粹的函数调用【禁止的就是这个】

情况二:作为对象方法的调用 【为对象的某个‘函数指针’服务】

情况三 作为构造函数调用【为对象本身的构造服务】

情况四 apply调用【这也要禁止】

    • apply()的参数为空时,默认调用全局对象:
  var x = 0;

  function test(){
    alert(this.x);
  }   var o={};
  o.x = 1;
  o.m = test;
  o.m.apply(); //0 ----> 如果是nodejs,则返回undefined,毕竟全局对象的表示有所差异
    • apply指定了对象,这时this代表的是对象o,此时就可以严格模式。

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

  • Function.caller

Ref: Js中caller和callee的区别

caller 返回一个调用当前函数的引用 如果是由顶层调用的话 则返回null。【就是眼球飞到外面,宏观的看到了自己的视角】

var callerTest = function() {
  console.log(callerTest.caller) ;
} ; function a() {
  callerTest() ;
} a() ;       // [Function: a] ----> 表示 调用calerTest这个函数的外层函数是a()
callerTest() ; // [Function]

callee 返回一个正在被执行函数的引用

var c = function(x,y) {
console.log(arguments.length, arguments.callee.length, arguments.callee)
} ; c(1,2,3) ;// 3, 2, [Function: c]
  • Function.arguments

Ref: js之arguments详解

借用arguments.callee来让匿名函数实现递归

var sum = function(n) {
if(n == 1) {
return 1;
} else {
return n + arguments.callee(n-1);   // 匿名函数,通过callee找到隐藏的自己的名字
 }
}
console.log("sum =", sum(5));

干脆就别用argments了,使用rest完全替代之。

  • 严格模式下则禁止此方法

function f1() {

    // "use strict";
console.log(f1.caller); // 报错
console.log(f1.arguments); // 报错
} f1();

同时, 禁止使用arguments.callee。

禁止随便删除变量

Ref: [JS] Topic - Object.create vs new

只有configurable设置为true的对象属性,才能被删除。

"use strict";

var x;
delete x; // 语法错误 var o = Object.create(null, {'x': {
  value: 1,
  configurable: true
}});
delete o.x; // 删除成功

显式报错,守住承诺

  • 对一个对象的只读属性进行赋值
"use strict";

var o = {};
Object.defineProperty(o, "v", { value: 1, writable: false }); o.v = 2; // 报错
  • 使用getter方法读取的属性进行赋值
"use strict";

var o = {
  get v() { return 1; }
};
o.v = 2; // 报错
  • 对禁止扩展的对象添加新属性
"use strict";

var o = {};
Object.preventExtensions(o);
o.v = 1; // 报错
  • 删除一个不可删除的属性
"use strict";

delete Object.prototype; // 报错

重名错误

重名属性不能后者覆盖前者。

函数也不能有重名。【以为是脚本,所以通过”参数位置“认定参数】

禁止八进制表示法

"use strict";
var n = 0100; // 语法错误

函数必须声明在顶层

将来Javascript的新版本会引入"块级作用域"。

不允许在非函数的代码块内声明函数。

保留字

implements, interface, let, package, private, protected, public, static, yield。

使用这些词作为变量名将会报错。

此外,ECMAscript第五版本身还规定了另一些保留字(class, enum, export, extends, import, super),

以及各大浏览器自行增加的const保留字,也是不能作为变量名的。

12种不宜使用的Javascript语法


Javascript中哪些部分是精粹,哪些部分是糟粕和鸡肋。

1. ==

永远只使用===和!==

因为==默认会进行类型转换,规则十分难记。

2. with

已提及

3. eval

创设eval作用域

"use strict";

var x = 2;
console.info(eval("var x = 5; x")); // 5
console.info(x); // 2 

However,

eval用来直接执行一个字符串。这条语句也是不应该使用的,因为它有性能和安全性的问题,并且使得代码更难阅读。

eval能够做到的事情,不用它也能做到。

4. continue 

循环本来就会返回到头部。所以通过适当的构造,完全可以避免使用这条命令,使得效率得到改善。

5. switch 贯穿

凡是有case的地方,一律加上break。

6. 单行的块结构

if、while、do和for,都是块结构语句,都一律加上大括号。

7. ++和--

不用为好。

8. 位运算符

Javascript内部,所有数字都保存为双精度浮点数。

故,没有效率优势。

9. function语句

在Javascript中定义一个函数,有两种写法:

function foo() { }      // ----> 会被解析器自动提升到代码的头部,违背了函数应该先定义后使用的要求

var foo = function () { }   // 推荐!

Ref: [JS] Topic - variable and function hoisting

10. 基本数据类型的包装对象

// 避免这种包装对象String、Number和Boolean的写法,完全没有必要!
new String("Hello World");
new Number(2000);
new Boolean(false);

另外,new Object和new Array也不建议使用,可以用{}和[]代替。

那就是用Object.create方法咯。

11. new语句

Javascript做出了妥协,采纳了畸形的类的概念

反例子

// 类是这样定义的:【有属性,有this,就是个类,不是函数】

  var Cat = function (name) {
    this.name = name;
    this.saying = 'meow' ;
  } // 然后,再生成一个对象   var myCat = new Cat('mimi');

建议不要这样创建对象,而采用一种变通方法。

// Douglas Crockford给出了一个自定义函数:

  Object.beget = function (o) {
    var F = function (o) {};
    F.prototype = o ;
    return new F;
  }; // 创建对象时就利用这个函数,对原型对象进行操作:   var Cat = {
    name:'',
    saying:'meow'
  };   var myCat = Object.beget(Cat);

// 对象生成后,可以自行对相关属性进行赋值:

    myCat.name = 'mimi';

Ref: [JS] Topic - define "class" by tricky methods

12. void

在大多数语言中,void都是一种类型,表示没有值。

但是在Javascript中,void是一个运算符,接受一个运算数,并返回undefined。

void 0; // undefined

这个命令没什么用,而且很令人困惑,建议避免使用。

[JS] Topic - why "strict mode" here的更多相关文章

  1. js 使用 "use strict"

    "use strict"是JavaScript中一个非常好的特性,而且非常容易使用. 使用方法 // file.js "use strict" function ...

  2. [JS] Topic - variable and function hoisting

    Ref: 深入理解js的变量提升和函数提升 一.变量提升 简直就是es5的遗毒! console.log(global); // undefined 竟然能打印?因为变量提升,下一行就有定义 var ...

  3. [JS] Topic - Object.create vs new

    故事背景 Ref: 你不知道的javascript之Object.create 和new区别 var Base = function () {} (1) var o1 = new Base(); (2 ...

  4. [JS] Topic - hijack this by "apply" and "call"

    Ref: 详解js中的apply与call的用法 call 和 apply二者的作用完全一样,只是接受参数的方式不太一样. 参数形式: Function.apply(obj,args) call方法与 ...

  5. [JS] Topic - this is ”closure“

    Ref: 为什么要用闭包? 背景 闭包是自带运行环境的函数 发哥是自带背景音乐的男人~ 就是有权访问另一个函数作用域的变量的函数. 函数式编程的闭包,就是函数的调味包.方便用户调用函数.不必为了维护繁 ...

  6. [JS] Topic - define "class" by tricky methods

    Ref:Javascript定义类(class)的三种方法 Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象.但是,它又不是一种真正的面向对象编程(O ...

  7. js:"use strict"; 严格模式

    http://www.ruanyifeng.com/blog/2013/01/javascript_strict_mode.html

  8. [Code::Blocks] Install wxWidgets & openCV

    The open source, cross platform, free C++ IDE. Code::Blocks is a free C++ IDE built to meet the most ...

  9. 本人SW知识体系导航 - Programming menu

    将感悟心得记于此,重启程序员模式. js, py, c++, java, php 融汇之全栈系列 [Full-stack] 快速上手开发 - React [Full-stack] 状态管理技巧 - R ...

随机推荐

  1. Codeforces Round #408 (Div. 2) 题解【ABCDE】

    A - Buying A House 题意:给你n个房间,妹子住在第m个房间,你有k块钱,你想买一个离妹子最近的房间.其中相邻的房间之间距离为10,a[i]=0表示已经被别人买了. 题解:扫一遍更新答 ...

  2. weblogic10 部署 spring+cxf ,调用时报:cannot create a secure XmlInputFactory

    weblogic10 部署 spring+cxf ,调用时报:cannot create a secure XmlInputFactory   一个cxf webservice项目部署到tomcat能 ...

  3. win2008R2管理员密码修改文档

    场景:忘记了win2008R2服务器的管理员密码.解决办法:1. 制作一个U盘启动盘:2. 系统通过U盘启动进入WINpe系统3. 在知道Win2008安装位置的情况下:查找C:\windows\sy ...

  4. VMWare Station 问题汇总

    1.开机黑屏,不启动系统 解决方法: 命令行窗口cmd—输入下面代码,然后重启计算机. netsh winsock reset 2.提示磁盘被锁无法打开 解决方法: 虚拟机目录下面的.lck文件都删了

  5. SRS流媒体服务器安装配置

    SRS全称Simple RTMP Server,定位是运营级的互联网直播服务器集群,是一个非常简单就可以推送rtmp视频流的服务器. github主页:https://github.com/ossrs ...

  6. (转) Java RandomAccessFile与MappedByteBuffer

    RandomAccessFile RandomAccessFile是用来访问那些保存数据记录的文件的,你就可以用seek( )方法来访问记录,并进行读写了.这些记录的大小不必相同:但是其大小和位置必须 ...

  7. 微信小程序 多个视频播放器

    大致思路就是,wx:for="{{ list }}"下两个view,一个视频video,另一个封面image(客户需求,要可以自定义封面).主要控制变量是playIndex,当点击 ...

  8. 数据库连接池优化配置(druid,dbcp,c3p0)

    主要描述了数据库连接池参数配置的准则,针对常用的数据库连接池(c3p0,dbcp,druid)给出推荐的配置. 考虑因素 1:当前连接DB的规模   2:并发情况 3:执行db的响应时间 配置考虑 1 ...

  9. [转]Visual Studio 2010 中安装Qt 5.1

    截至目前(2013年7月12日)为止,Qt 的最高版本为Qt5.1,在该版本中已经将Qt Creator与Qt Lib集成在一个文件夹中,因此安装的时候较为方便,只需安装一个即可.因为Qt具有超强的可 ...

  10. 移除list中null元素

    查询结果为null, list.size()却是1 移除该null元素 totalList.removeAll(Collections.singleton(null));