JavaScript中的数据类型

Posted on

隔了一个月,我又来发博客了。最近的工作老是在写CSS和HTML。但是我更想学习JS啊!我一直都觉得HTML和CSS是属于设计范畴的,而JS才是真正属于工程师的逻辑范畴。 况且最近Github上有一个神奇的项目Screenshot-to-code-in-Keras可以把截图直接生成HTML代码,我觉得只是单纯的从PSD翻译成页面的工作迟早要被淘汰。

最近在读You Don't Know JS这本书。书上讲解了很多关于JS的细节知识,对于深入了解JS有很大帮助。所以想在读的过程中把一些觉得有意思的东西记下来,便于以后复习。

类型

JavaScript中有七种内置类型:

  1. 空值(null)
  2. 未定义(undefined)
  3. 布尔值(boolean)
  4. 数字(number)
  5. 字符串(string)
  6. 对象(object)
  7. 符号(symbol, ES6新增)

除了对象之外,通称基本类型。

JavaScript中的设计BUG

typeof null === "object"; // true

正确的返回结果应该是null。但这个BUG由来已久,修复反而会出问题。所以我们需要使用复合条件来判断:

(!a && typeof a === "object")

接下来是NaN的问题:

var a = 2 / "foo";
var b = "foo";
a; // NaN
b; "foo"
window.isNaN( a ); // true
window.isNaN( b ); // true
NaN === NaN // false

很显然"foo"不是NaN,但显然它也不是数字。这个BUG也存在很久了,在ES6时代,我们可以使用Number.isNaN来解决。 ES6之前的polyfill是:

if (!Number.isNaN) {
  Number.isNaN = function(n) {
    return (
      typeof n === "number" &&
      window.isNaN(n)
    );
  };
}

并且NaN是JS中唯一一个不等于自身的值。

值和类型

JavaScript中的变量是没有类型的,只有值才有。变量可以随时持有任何类型的值。

undefined 和 undeclared. 变量在未持有的时候为undefined, 此时typeof 返回 undefined. 大多数开发者倾向于将 undefined 等同于 undeclared(未声明),但在 JavaScript 中它们完全是两回事。已在作用域中声明但还没有赋值的变量,是 undefined 的。相反,还没有在作用域中声明过的变量,是 undeclared 的。

var a;
a; // undefined
b; // ReferenceError: b is not defined
typeof a; // "undefined"
typeof b; // "undefined"

虽然b 是一个 undeclared 变量,但 typeof b 并没有报错。这是因为 typeof 有一个特殊的安全防范机制。防止因为未定义导致程序终止运行。

值和引用

在许多编程语言中,赋值和参数传递可以通过值复制(value-copy)或者引用复制(reference-copy)来完成,这取决与我们使用什么语法。但是JavaScript 对值和引用的赋值 / 传递在语法上没有区别,完全根据值的类型来决定。

简单值(即标量基本类型值,scalar primitive)总是通过值复制的方式来赋值/传递,包括null 、 undefined 、字符串、数字、布尔和 ES6 中的 symbol 。

复合值(compound value)——对象(包括数组和封装对象)和函数,则总是通过引用复制的方式来赋值/传递。由于引用指向的是值本身而非变量,所以一个引用无法更改另一个引用的指向。

var a
var b
a; //
b; //
= [1,2,3];
= a;
[1,2,3]
[1,2,3]
// 然后
b = [4,5,6];
a; // [1,2,3]
b; // [4,5,6]

b=[4,5,6] 并不影响 a 指向值 [1,2,3] ,除非 b 不是指向数组的引用,而是指向 a 的指针,但在 JavaScript 中不存在这种情况!

参考:

You Don't Know JS

前端开发的技术栈

Posted on

我发现自己博客没次开头都是在说近况和废话。这次也不例外。哈哈哈,工作也算顺畅,顺便总结下最近的前端开发的技术栈来回顾下这半年学到的知识。

HTML开发

对于大型项目,直接书写HTML代码是一个非常繁琐和头疼的事情,因为HTML需要闭合,每次找匹配的HTML标签都要非常花功夫。所以现在的开发都是使用预处理器来书写代码,例如主流的Pug,通过缩进来控制元素的嵌套,还支持多种语法。非常适合大型项目的开发,再也不用担心修改代码的时候出现HTML元素标签没有闭合的情况发生了。而且还规避了一些语法错误,例如在p标签里嵌入block元素是非法的。如果强行嵌入的话,你会发现生成的HTML代码是错误的。

CSS开发

CSS开发更多的需要是良好的模块化功能和合理的作用域。这时候也需要通过预处理器来进行操作,推荐使用SCSS。这里很多人对sassscss之间的区别有疑问。简单的来说,SCSS的格式更接近CSS,所以比较容易上手。但是SASS是通过缩进来书写的,对新手不太友好。所以建议大家使用SCSS来书写模块化代码。

JavaScript开发

现在主流的浏览器支持的JavaScript版本是es5。但是众所周知,JavaScript(es5)有很多陷阱和缺点,例如this指针问题和异步处理等等。基于原型连的继承对于面向对象开发者来说也很不友好。所以推荐使用es6来书写代码。可以使用基于class的继承,和解决this指针问题。而且还能使用import进行模块化开发。虽然只是语法糖,但也提升了开发效率。

自动化构建工具

我们使用了预处理器来书写代码,并使用新版本的es6语法。但是目前浏览器并不支持直接解析这些内容。所以我们需要构建化工具来处理从Pug生成HTML,从SCSS生成CSS,把es6语法的JavaScript转换成es5语法。对于SPA网站推荐使用webpack,而对于普通网站的构建推荐使用Gulp。这里区别开的原因是,webpack必须指定入口文件,但是Gulp只需要指定需要处理的文件或文件夹就可以了,支持通配符匹配。对于多页面的传统网站来说非常便利。

浏览器兼容处理

这是每个前端工程师最头疼的地方了,因为每个浏览器支持程度都不一样。在使用比较新的API记得去Can I use查看下各个浏览器的支持情况,如果实在是需要这个功能的话,那就只能去寻找polyfill了。

参考:

Why p tag can't contain div tag