JavaScript中的一些小知识点,需要了解。
with语句
with语句:扩展一个语句的作用域链。(不推荐使用)
// 简单的代码
var message = "copyer";
function foo() {
console.log(message);
}
foo();
查找message的作用域链:
// with语句
var message = "copyer";
var withObj = { message: "with语句中的message" };
function foo() {
with (withObj) {
console.log(message); // with语句中的message
}
}
foo();
查找message的作用域链
这里就是在作用域链加上了一个with的作用域,如果找到了message就停止寻找。
具体使用:
with语句 跟 if语句形式是差不多的,都是后面跟上一个小括号。
- if 括号里面存放条件
- with 括号里面存放一个变量,在
with的作用域中,就存放该变量。
eval函数
eval是一个特殊的函数,它可以将传入的字符串当做JavaScript代码执行。(不推荐使用)
const str = 'var message = "copyer"; console.log(message);'
eval(str) // copyer
console.log(message) // copyer
eval解析字符串成JavaScript代码,也就相当于普通的代码执行,所以在外面也能访问里面的变量。
后面学习到的知识
(function() {
(0,eval)("var foo = 123"); // indirect call to eval, creates global variable
})();
console.log(foo); // 123
(function() {
eval("var bar = 123"); // direct call to eval, creates local variable
})();
console.log(bar); // ReferenceError
stackoverflow.com/questions/4…
不推荐使用的原因:
- eval的代码可读性非常差(代码的可读性是高质量代码的重要原则)。
- eval执行必须经过JS的解释器,不能被JS引擎优化。
严格模式
在ECMAScript5中,JavaScript提出严格模式的概念(Strict Moda)。
JavaScript的语法过于灵活,严格模式就是用来限制JavaScript过于灵活的写法。
message = 'copyer' // 没有使用关键词 var 来定义变量,以致于message保存在window上(变量污染)
true.name = 'copyer' // 毫无意义的写法,但是也不会保错
var obj = {};
Object.defineProperty(obj, "message", {
writable: false, // 给对象对象添加不可编辑的特性
value: "copyer",
});
console.log(obj.message);
obj.message = 'kobe' // 也可直接编辑,没有报错(虽然也没有修改成功)
还有很多的(无意义)的写法,JavaScript都不会报语法错误。
所以严格模式就产生了,需要限制一下,直接报语法错误等信息。
支持严格模式的浏览器在检测代码中有严格模式时,会以更加严格的方式对代码进行检测和执行。
严格模式对正常的JavaScript语法进行一些限制:
- 严格模式通过
抛出错误来抛出一些语法错误 - 严格模式让JS引擎在执行代码时进行更多的优化(不需要对一些特殊的语法进行处理)
开启严格模式的方式:
- 针对整个JS文件:在js文件的第一行:
use strict - 针对某个函数:在函数体内的第一行:
use strict
严格模式的限制
1、无法意外的创建全局变量
"use strict";
message = 'copyer'
// 报错: Uncaught ReferenceError: message is not defined
2、对无意义的写法,抛出异常
"use strict";
true.name = 'copyer'
// 报错:Uncaught TypeError: Cannot create property 'name' on boolean 'true'
3、对不可编辑的属性进行修改(或则删除)
"use strict";
var obj = {};
Object.defineProperty(obj, "message", {
writable: false, // 给对象对象添加不可编辑的特性
value: "copyer",
});
obj.message = 'kobe'
// 报错:buchong.js:7 Uncaught TypeError: Cannot assign to read only property 'message' of object '#<Object>'
4、不允许函数参数具有相同的名称
"use strict";
function foo(a,b,a) {
// a: 30
}
foo(10,20,30)
// 报错:Uncaught SyntaxError: Duplicate parameter name not allowed in this context
5、严格模式下,不能使用with语句
6、eval函数不在为上层引用变量
"use strict";
const str = 'var message = "copyer"; console.log(message);'
eval(str) // copyer
console.log(message) // Uncaught ReferenceError: message is not defined
7、this的指向: 默认绑定的this为undefined
"use strict";
foo() {
console.log(this) // undefined
}
foo()
setTimeout(() => {
console.log(this) // 箭头函数:window
}, 10)
setTimeout(function () {
console.log(this) // 普通函数: window
}, 10)
\