[JS] Topic - why "strict mode" here
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的更多相关文章
- js 使用 "use strict"
"use strict"是JavaScript中一个非常好的特性,而且非常容易使用. 使用方法 // file.js "use strict" function ...
- [JS] Topic - variable and function hoisting
Ref: 深入理解js的变量提升和函数提升 一.变量提升 简直就是es5的遗毒! console.log(global); // undefined 竟然能打印?因为变量提升,下一行就有定义 var ...
- [JS] Topic - Object.create vs new
故事背景 Ref: 你不知道的javascript之Object.create 和new区别 var Base = function () {} (1) var o1 = new Base(); (2 ...
- [JS] Topic - hijack this by "apply" and "call"
Ref: 详解js中的apply与call的用法 call 和 apply二者的作用完全一样,只是接受参数的方式不太一样. 参数形式: Function.apply(obj,args) call方法与 ...
- [JS] Topic - this is ”closure“
Ref: 为什么要用闭包? 背景 闭包是自带运行环境的函数 发哥是自带背景音乐的男人~ 就是有权访问另一个函数作用域的变量的函数. 函数式编程的闭包,就是函数的调味包.方便用户调用函数.不必为了维护繁 ...
- [JS] Topic - define "class" by tricky methods
Ref:Javascript定义类(class)的三种方法 Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象.但是,它又不是一种真正的面向对象编程(O ...
- js:"use strict"; 严格模式
http://www.ruanyifeng.com/blog/2013/01/javascript_strict_mode.html
- [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 ...
- 本人SW知识体系导航 - Programming menu
将感悟心得记于此,重启程序员模式. js, py, c++, java, php 融汇之全栈系列 [Full-stack] 快速上手开发 - React [Full-stack] 状态管理技巧 - R ...
随机推荐
- linux <<eof
在平时的运维工作中,我们经常会碰到这样一个场景:执行脚本的时候,需要往一个文件里自动输入N行内容.如果是少数的几行内容,还可以用echo追加方式,但如果是很多行,那么单纯用echo追加的方式就显得愚蠢 ...
- (转)Fur Shader
转自:http://qiankanglai.me/misc/2014/11/15/fur-shader/ 花时间看了下毛发效果,苦于囊中羞涩没能买QuickFur.furFX等插件,最后找到了Fur ...
- http://jqweui.com/
http://jqweui.com/ jQuery WeUI jQuery WeUI 是专为微信公众账号开发而设计的一个简洁而强大的UI库,包含全部WeUI官方的CSS组件,并且额外提供了大量的拓展组 ...
- Java 下一代: 函数式编码风格——Groovy、Scala 和 Clojure 共享的函数结构及其优势
原文地址 本文内容 命令式处理 函数式处理 函数式编程的优势 所有 Java 下一代语言都包括函数式编程结构,让您可以从一个更高的抽象层面来思考问题.然而,语言间术语的不同使得难以看到类似的结构.本期 ...
- ls(ll)排序问题
ls(ll)排序问题 1.按照时间倒叙排列—— -lnt ( LNT,大写备注区分一下) 2.安照时间正序排列—— -lrt (LRT) 3.按照文件名正序排序(默认的排序方式)—— -l 4.按照文 ...
- Win10更新搜狗输入法后重启输入密码蓝屏
解决办法:如果能进入安全模式,卸载搜狗输入法:不行的话(好像不行)只能重装系统:因为蓝屏后就基本开不了了!!!生气!! win10 1809 19.3月累积更新之后蓝屏:安装了搜狗输入法的win10 ...
- javascript回调函数笔记
来源于:https://github.com/useaname/blog-study 在Javascript中,函数是第一类对象.意味函数可以像对象一样按照第一类被管理使用.回调函数是从一个叫函数式编 ...
- 11G新特性 -- OLTP Table Compression
之前的版本中,只能在批量加载操作时,比如direct load.create table as select 操作,才能压缩数据.在dml操作期间是无法压缩数据的. 在11g中,oracle将表压缩扩 ...
- 11G新特性 -- variable size extents
AU是asm磁盘分配的基本单元.在oracle10g中,一个AU对应一个extent(这会增加对内存的使用),因为一个大的数据库如果含有大量的默认大小的AU,会导致数据库的share pool的大量使 ...
- 5 Protocols For Event-Driven API Architectures
The internet is a system of communication, and as such, the relationship between client and server, ...