突然想起来我是个前端 =-= 在公司没事的时候,就看看书写点文章。

Null

typeof null === “object”;// true

正确的返回结果应该是 “null”,但这个 bug 由来已久,在 JavaScript 中已经存在了将近二十年,也许永远也不会修复,因为这牵涉到太多的 Web 系统,“修复” 它会产生更多的 bug,令许多系统无法正常工作;

我们需要使用复合条件来检测 null 值的类型:

var a = null;

(!a && typeof a === ‘object’);

值和类型

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

遗憾的是,JavaScript 却将它们混为一谈,在我们试图访问 “undeclared” 变量时这样报错:ReferenceError:a is not defined,并且 typeof 对 undefined 和 undeclared 变量都返回 “undefined”

typeof 的安全防范机制(阻止报错)来检查 undeclared 变量

### 数组

如果字符串键值能够把强制类型转换为十进制数字的话,它就会被当作数字索引来处理。 建议使用对象来存放键值 / 属性值

Array.from

字符串

js 中的字符串是不可变的,而数组是可变的。

字符串不可变是指字符串的成员函数不会改变其原始值,而是创建并返回一个新的字符串。而数组的成员函数都是在其原始值上进行操作

不是值的值

  • null 指空值

  • undefined 指没有指

或者:

  • undefined 指从未赋值

  • null 指曾赋过值,但是目前没有指

null 是一个特殊关键字,不是标识符,我们不能将其当作变量来使用和赋值。然而 undefined 却是一个标识符,可以被当作变量来使用和赋值

特殊等式

ES6 之前的版本,object.js()来判断两个值是否绝对相等。

var a = 2 / "foo";
var b = -3 *0;
Object.JS(a,NaN);
object.js(b,-o);
object.is(b,0)

ERROR

带不带关键字都可。主要是为了获取当前运行栈的上下文。我目前见到的运用是防爬虫爬api接口

JSON.stringify

JSON.stringify 在对象中遇到 undefined,function,和 symbol时会自动将其忽略,在数组中则会返回 null

var a = {
    a : 42,
    c : "42",
    d : [1,2,3]
}
JSON.stringify(a,["b","c"]);
JSON.stringify(a,function(k,v){
    if(k !== "c") return v;
})

### 宽松相等和严格相等

“== 允许在相等比较中进行强制类型转换,而 === 不允许”

字符串和数字之间的相等比较

如果 Type(x) 是数字,Type(y) 是字符串,则返回 x == ToNumber(y) 的结果。

如果 Type(X) 是字符串,Type(y) 是数字,则返回 ToNumber(x) == y 的结果。

其他类型和布尔类型之间的相等比较

如果 Type(x) 是布尔类型,则返回 ToNumber(x) ==y 的结果。

如果 Type(y) 是布尔类型,则返回 x == ToNumber(y) 的结果。

null 和 undefined 之间的相等比较

如果 x 为 null,y 为 undefined ,则结果为 true

如果 x 为 undefined,y为 null,则结果为 true

对象和非对象之间的相等比较

如果 Type(x) 是字符串或数字,Type(y) 是对象,则返回 x == ToPrimitive(y)的结果;

如果 Type(x) 是对象,Type(y)是字符串或数字,则返回 ToPrimitive(x) == y 的结果;

var a = 42;
var b = [42];
a === b; //false
a == b; //true

a == b 结果为 true,因为 b 通过 ToPrimitive 进行强制类型转换

也称为 “拆封”,英文为 unboxed 或者 unwrapped,并返回标量基本类型值 “abc”,于 a 相等

var a = null;
var b = object(a); //和 object() 一样
a == b; //false

var c = undefined;
var d = object(c); //和 object() 一样
c == d;  //false

var e = NaN; 
var f = Object(e); //和new Number(e) 一样
e == f;  //false

表达式的副作用

var a = 42;
var b = a++;
a; //43
b; //42

a++ 首先返回变量 a 的当前值(再将该值赋给b)然后将a的值+1;

var a = 42,b;
b = (a++,a);
a;43
b;43

|| 和 &&

&& 和 || 运算符的返回值并不一定是 布尔类型,而是两个操作数其中一个的值。

|| 和 && 首先会第一个操作数(a和c)执行条件判断,如果其不是布尔值就会进行 ToBoolean 强制类型转换,然后再执行条件判断。

对于 || 来说,如果条件判断结果为 true 就返回第一个操作数(a和c)的值.。

&&则相反.

运算符优先级

var a = 42;
var b = "foo";
var c = [1,2,3];


a && b || c ; //"foo"
a || b && c; // 42  ? &&元素符先于 || 执行,并不是从左到右

用 , 来连接一系列语句的时候,它的优先级最低,其他操作数的优先级都比它高。

全局 DOM 变量

<div id="foo"></div>
以及:
if(typeof foo == "undefinen"){
    foo = 42; //永远也不会运行
}

console.log(foo)// HTML元素

script

绝大部分网站/Web应用程序的代码都存放在多个文件中,通常可以在网页中使用 script src或 sript> < sript加载文件。

思考

这些文件和内联代码是相互独立的 JavaScript 程序还是一个整体呢?

它们的运行方式更像是相互独立的 JavaScript 程序,但是并非总是如此。

它们共享 global 对象(在浏览器中则是 window),也就是说这些文件中的代码在共享的命名空间中运行,并相互交互。

如果 js 代码,发送错误,它会像独立的 js 程序那样停止,但是后续的 js 代码(仍然共享 global)依然会接着运行,不会受影响。