'use strict';consts='Hi! I\'m a strict mode script!';
1.2 特定函数
为特定函数启用严格模式。
functionmyStrictFunction() {// 函数级的严格模式'use strict';functionnested() {return'And so am I!'; }return`Hi! I'm a strict mode function! ${nested()}`;}functionmyNotStrictFunction() {return'I\'m not strict.';}
'use strict';mistypeVarible =33; // ReferenceError: mistypeVarible is not definedfunctionf() { a =1; // ReferenceError: a is not defined}f();console.log(this.a);// non-strict mode 会创建一个全局变量
'use strict';// 给全局变量赋值NaN=2; // TypeError: Cannot assign to read only property 'NaN' of object '#<Window>'undefined=true; // TypeError: Cannot assign to read only property 'undefined' of object '#<Window>'// 给不可写的属性赋值consto= {};Object.defineProperty(o,"x", { value:1, writable:false });o.x =2; // TypeError: Cannot assign to read only property 'x' of object '#<Object>'console.log(o.x);// 给仅 getter 的属性赋值consto1= {getx() {return1; }};o1.x =2; // TypeError: Cannot set property x of #<Object> which has only a getterconsole.log(o1.x);// 给不可扩展对象的新属性赋值constfixed= {};Object.preventExtensions(fixed);fixed.newProp ='hi'; // TypeError: Cannot add property newProp, object is not extensibleconsole.log(fixed);// non-strict mode 会依次输出:// 1// 1// {}
第三,删除不可删除的属性。
'use strict';// TypeError: Cannot delete property 'prototype' of function Object() { [native code] }deleteObject.prototype;
第四,函数的参数名必须唯一。
// SyntaxError: Duplicate parameter name not allowed in this contextfunctionsum(a, b, c, a) {'use strict';return a + b + c;}
第五,禁止以 0 为前缀的八进制文字或八进制转义序列。
'use strict';var n =010; // SyntaxError: Octal literals are not allowed in strict mode.console.log(n); // non-strict mode 会输出 8,因为被当成了八进制
第六,禁止在原始值上设置属性。
'use strict';false.true =''; // TypeError: Cannot create property 'true' on boolean 'false'(14).sailing ='home'; // TypeError: Cannot create property 'sailing' on number '14''with'.you ='far away'; // TypeError: Cannot create property 'you' on string 'with'// non-strict mode 虽没报错,但其实是执行失败了——没啥效果
'use strict';eval =''; // SyntaxError: Unexpected eval or arguments in strict modearguments = []; // SyntaxError: Unexpected eval or arguments in strict mode
'use strict';functionadd(a, b) { arguments[0] =11; b =22;console.log(a, b);return a + b;}add(1,2);// non-strict mode: 11 22// strict mode: 1 22
'use strict';// TypeError: // 'caller', 'callee', and 'arguments' properties may not be accessed // on strict mode functions or the arguments objects for calls to themfunctionfn() {return arguments.callee;}fn();
'use strict';functionfn() {console.log(this); // undefinedthis.a =1; // TypeError: Cannot set properties of undefined (setting 'a')console.log(this.a); // TypeError: Cannot read properties of undefined (reading 'a')}fn(); // 等价于 fn.call();
eg3. 通过 call(), apply() 或 bind() 给函数指定特定的 this
'use strict';functionfn() {this.a =1;console.log(this);console.log(this.a);}consto= { a:10, b:11 };fn.call(o);// {a: 1, b: 11}// 1fn.call({});// {a: 1}// 1fn.call(null);// TypeError: Cannot set properties of null (setting 'a')// null// TypeError: Cannot read properties of null (reading 'a')fn.call();// TypeError: Cannot set properties of undefined (setting 'a')// undefined// TypeError: Cannot read properties of undefined (reading 'a')
2.5.2 函数栈不可追踪
当一个函数 fun 被调用时,fun.caller 表示最近调用 fun 的函数,fun.arguments 表示调用 fun 的参数。考虑到有些 ECMAScript 扩展会通过 fun.caller 和 fun.arguments 得到 JavaScript 的调用堆栈,所以严格模式中 fun.caller 和 fun.arguments 这两个属性都是不可删除的,在设置和检索时会报错。如下:
non-deletable properties, set or retrieved
functionfn() {'use strict';// TypeError: // 'caller', 'callee', and 'arguments' properties may not be accessed// on strict mode functions or the arguments objects for calls to themfn.caller;fn.arguments;}functionprivilegedInvoker() {returnfn();}privilegedInvoker();