
2024-12-24 日报 Day45

今日的鸡汤
很多时候,能力决定你能走多快,人品决定你能走多远。
今日学习内容
1、JS红皮书P128-131 第五章:基本引用类型
今日笔记
1、HTML:早期的浏览器开发商认为使用 JavaScript 动态生成 HTML 标签是一个需求。因此,早期浏览器扩展了规范,增加了辅助生成 HTML 标签的方法。下表总结了这些 HTML 方法。不过,这些方法基本上已经没有人使用了,因为结果通常不是语义化的标记。
方 法 | 输 出 |
---|---|
anchor(name) | string |
big() | string |
bold() | string |
fixed() | string |
fontcolor(color) | string |
fontsize(size) | string |
italics() | string |
link(url) | string |
small() | string |
strike() | |
sub() | string |
sup() | string |
2、单例内置对象:ECMA-262 对内置对象的定义是“任何由 ECMAScript 实现提供、与宿主环境无关,并在 ECMAScript程序开始执行时就存在的对象”。这就意味着,开发者不用显式地实例化内置对象,因为它们已经实例化好了。前面我们已经接触了大部分内置对象,包括 Object、Array 和 String。本节介绍 ECMA-262定义的另外两个单例内置对象:Global 和 Math。 |
- Global:Global 对象是 ECMAScript 中最特别的对象,因为代码不会显式地访问它。ECMA-262 规定 Global对象为一种兜底对象,它所针对的是不属于任何对象的属性和方法。事实上,不存在全局变量或全局函数这种东西。在全局作用域中定义的变量和函数都会变成 Global 对象的属性 。本书前面介绍的函数,包括 isNaN()、isFinite()、parseInt()和 parseFloat(),实际上都是 Global 对象的方法。除了这些,Global 对象上还有另外一些方法。
URL编码方法:encodeURI()和 encodeURIComponent()方法用于编码统一资源标识符(URI),以便传给浏览器。有效的 URI 不能包含某些字符,比如空格。使用 URI 编码方法来编码 URI 可以让浏览器能够理解它们,同时又以特殊的 UTF-8 编码替换掉所有无效字符。
ecnodeURI()方法用于对整个 URI 进行编码,比如”www.wrox.com/illegal value.js”。而encodeURIComponent()方法用于编码 URI 中单独的组件,比如前面 URL 中的”illegal value.js”。这两个方法的主要区别是,encodeURI()不会编码属于 URL 组件的特殊字符,比如冒号、斜杠、问号、井号,而 encodeURIComponent()会编码它发现的所有非标准字符。来看下面的例子:这里使用 encodeURI()编码后,除空格被替换为%20 之外,没有任何变化。而 encodeURIComponent()方法将所有非字母字符都替换成了相应的编码形式。这就是使用 encodeURI()编码整个URI,但只使用 encodeURIComponent()编码那些会追加到已有 URI 后面的字符串的原因。1
2
3
4
5let uri = "http://www.wrox.com/illegal value.js#start";
// "http://www.wrox.com/illegal%20value.js#start"
console.log(encodeURI(uri));
// "http%3A%2F%2Fwww.wrox.com%2Fillegal%20value.js%23start"
console.log(encodeURIComponent(uri));
与 encodeURI()和 encodeURIComponent()相对的是 decodeURI()和 decodeURIComponent()。decodeURI()只对使用 encodeURI()编码过的字符解码。例如,%20 会被替换为空格,但%23 不会被替换为井号(#),因为井号不是由 encodeURI()替换的。类似地,decodeURIComponent()解码所有被 encodeURIComponent()编码的字符,基本上就是解码所有特殊值。来看下面的例子:这里,uri 变量中包含一个使用 encodeURIComponent()编码过的字符串。首先输出的是使用decodeURI()解码的结果,可以看到只用空格替换了%20。然后是使用 decodeURIComponent()解码的结果,其中替换了所有特殊字符,并输出了没有包含任何转义的字符串。(这个字符串不是有效的 URL。)1
2
3
4
5let uri = "http%3A%2F%2Fwww.wrox.com%2Fillegal%20value.js%23start";
// http%3A%2F%2Fwww.wrox.com%2Fillegal value.js%23start
console.log(decodeURI(uri));
// http:// www.wrox.com/illegal value.js#start
console.log(decodeURIComponent(uri));
3、eval()方法:eval()方法是 ECMAScript 中最强大的函数之一,也是最容易被滥用的函数之一。它的用途是将对应的字符串解析成 JS 代码并运行。来看下面的例子:当解释器发现 eval()调用时,会将参数解释为实际的 ECMAScript 语句,然后将其插入到该位置。通过 eval()执行的代码属于该调用所在上下文,被执行的代码与该上下文拥有相同的作用域链。这意味着定义在包含上下文中的变量可以在 eval()调用内部被引用,比如下面这个例子:1
eval("console.log('hi')");
注意 解释代码字符串的能力是非常强大的,但也非常危险。在使用 eval()的时候必须极为慎重,特别是在解释用户输入的内容时。因为这个方法会对 XSS 利用暴露出很大的攻击面。恶意用户可能插入会导致你网站或应用崩溃的代码。1
2let msg = "hello world";
eval("console.log(msg)"); // "hello world"
4、Global对象属性:Global 对象有很多属性,其中一些前面已经提到过了。像 undefined、NaN 和 Infinity 等特殊值都是 Global 对象的属性。此外,所有原生引用类型构造函数,比如 Object 和 Function,也都是Global 对象的属性。下表列出了所有这些属性。
属 性 | 说 明 |
---|---|
undefined | 特殊值 undefined |
NaN | 特殊值 NaN |
Infinity | 特殊值 Infinity |
Object | 构造函数 Object |
Array | 构造函数 Array |
Function | 构造函数 Function |
Boolean | 构造函数 Boolean |
String | 构造函数 String |
Number | 构造函数 Number |
Date | 构造函数 Date |
RegExp | 构造函数 RegExp |
Symbol | 构造函数 Symbol |
Error | 构造函数 Error(所有错误类型的基类型) |
EvalError | 构造函数 EvalError |
RangeError | 构造函数 RangeError |
ReferenceError | 构造函数 ReferenceError |
SyntaxError | 构造函数 SyntaxError |
TypeError | 构造函数 TypeError |
URIError | 构造函数 URIError |
5、window对象:虽然 ECMA-262 没有规定直接访问 Global 对象的方式,但浏览器将 window 对象实现为 Global对象的代理。因此,所有全局作用域中声明的变量和函数都变成了 window 的属性。来看下面的例子: |
1 | var color = "red"; |
另一种获取 Global 对象的方式是使用如下的代码:
let global = function() {
return this;
}();
这段代码创建一个立即调用的函数表达式,返回了 this 的值。如前所述,当一个函数在没有明确(通过成为某个对象的方法,或者通过 call()/apply())指定 this 值的情况下执行时,this 值等于Global 对象。因此,调用一个简单返回 this 的函数是在任何执行上下文中获取 Global 对象的通用方式。