前言
最近找时间读了"你不知道的javascript",公司导师要求应该要有一些产出,所以随笔记录下。顺便完善下自己的知识结构体系。但我读的顺序却很奇葩,从中再到上,最后再读下,最近又听了winter的重学前端,所以文章讲述的顺序可能与书目录的顺序不一致并且夹杂一下其他的感悟。
正文
内置类型
- 数字(number)
- 字符串(string)
- 布尔值(boolean)
- 未定义(undefined)
- 空值(null)
- 对象(object)
- 符号(symbol -> ES6)
我们可以使用 typeof 运算符来查看值的类型,但这七种类型和它们的字符串值并不是一一对应的, 以下是其中特殊的个例:
typeof null === 'object'; // true
问题来了,我们期待的结果应该是
typeof null === 'null'; // true
书中明确给出了答案。实际上这是一个 js 存在了将近20年的 bug,也许永远都不会修复,因为牵涉太多的 web 系统,一旦修复可能导致更多bug,使这些系统无法正常的工作。
同时书中也给出了用复合条件检测null的类型:
var a = null;
(!a && typeof a === "object"); // true
null 是基本类型中唯一的一个“假值”类型typeof对它返回值是'object'
复制代码
还有一种情况:
typeof function a(){ /* .. */ } === "function"; // true
看起来, function 函数应该也是一个内置类型, 但实际上它是 object 的一个 "子类型";
具体来说, 函数是 "可调用的对象", 它有一个内部属性 [[call]], 该属性使其能够被调用;
既然函数是对象, 那么它就应该有自己的属性:
function test(a, b, c) {
/* .. */
}
test.length // 3
因为该函数声明了三个命名参数,a、b 和 c,所以其 length 值为 3
复制代码
可以看到, 函数的 length 属性指的是其参数的个数
再来看看数组。JavaScript 支持数组,那么它是否也是一个特殊类型?
typeof [] === 'object'; // true
// 数组也是对象, 它是 object 的一个子类型,数组的元素按数字顺序来进行索引(而非普通像对象那样通过字符串键值),其 length 属性是元 素的个数。
复制代码
typeof
typeof 运算符总是会返回一个字符串
typeof typeof 42; // string
复制代码
该表达式, 首先会执行 typeof 42 返回字符串 number, 再执行 typeof 'number', 返回 string
值和类型
JavaScript 中的变量是没有类型的,只有值才有。变量可以随时持有任何类型的值。 也就是说, 语言引擎不要求变量总是持有与其初始值同类型的值, 我们可以随时修改变量的值的类型:
var a = 1;
typeof a === 'number' //true
a = "1"
typeof a === 'string' //true
复制代码
undefined 和 undeclared
undefined 即变量已被声明, 但未被赋值,undeclared 即没在作用域中声明过的变量;
访问已声明但未赋值的变量 (undefined), 浏览器会返回 undefined; 访问从未在作用域中声明的变量 (undeclared), 则会抛出错误:
var a;
console.log(a) // undefined
console.log(b) // ReferenceError: b is not defined
复制代码
上例中,“b is not defined”容易让人误以为是“b is undefined”。此时如果浏览器 报错成“b is not found”或者“b is not declared”会更准确。
再举个typeof的?
var a;
typeof a; // "undefined"
typeof b; // "undefined"
复制代码
所以要引出一个typeof的安全防范机制的概念
typeof 的安全机制
该安全防范机制对在浏览器中运行的 JavaScript 代码来说还是很有帮助的,因为多个脚本 文件会在共享的全局命名空间中加载变量。
举个?
我们有一个变量叫做 DEBUG, 该变量存放在 dev.js 中, 该 js 文件只会在开发环境被调用, 我们需要在另一个 js 文件中判断 DEBUG 变量是否存在, 而进行接下来的操作
// app.js
if (DEBUG) {
/* ... */
}
复制代码
如上代码, 如果在生产环境, 浏览器肯定会抛出异常 ReferenceError: DEBUG is not defined, 从而阻断 js 的运行;
这种情况, 我们就可以通过 typeof 的安全机制来解决这个问题:
if (typeof DEBUG !== 'undefined') {
/* ... */
}
复制代码
小结
JavaScript 有 七 种 内 置 类 型:null、undefined、boolean、number、string、object 和 symbol,可以使用 typeof 运算符来查看。
变量没有类型,但它们持有的值有类型。类型定义了值的行为特征。
很多开发人员将 undefined 和 undeclared 混为一谈,但在 JavaScript 中它们是两码事。 undefined 是值的一种。undeclared 则表示变量还没有被声明过。
遗憾的是,JavaScript 却将它们混为一谈,在我们试图访问 "undeclared" 变量时这样报 错:ReferenceError: a is not defined, 并 且 typeof 对 undefined 和 undeclared 变 量 都 返 回 "undefined"。
然而,通过 typeof 的安全防范机制(阻止报错)来检查 undeclared 变量,有时是个不错的 办法。
感悟
第一章给我的感觉是知识的范围不是特别广,所以特意读了winter的重学前端,winter开篇就提出了几个问题。如下:
- 为什么有的编程规范要求用 void 0 代替 undefined
- 字符串有最大长度吗
- 0.1 + 0.2 不是等于 0.3 么?为什么 JavaScript不是这样的
- ES6的symbol是个什么玩应儿
- 为什么给对象添加的方法能用在基本类型上?
后续文章结合于此书没有给出的知识点给出这些问题的答案~
希望大家都能找到适合自己的学习方法重学前端,完善自己的知识体系架构~