-
市场上的主流浏览器及其内核
浏览器分为 shell(外壳样式) 和 内核
这里引用一位大佬的文章:五大主流浏览器及四大内核 -
js中,switch语句后面的表达式,与case语句后面的表示式比较运行结果时,采用的是严格相等运算符(= = =),而不是相等运算符(= =),这意味着比较时不会发生类型转换。
-
js中,使用 var 创建的全局变量(实质是window的属性),不能使用 delete 删除,但是不使用 var 创建的全局变量(实质也是window的属性),可以使用 delete 删除。因为使用 var 创建的变量,其内置属性中的 configurable 属性默认为 false ,所以不能删除
-
js中,空数组([])和空对象({})对应的布尔值,都是true。
-
JavaScript 语言的底层根本没有整数,所有数字都是以64位浮点数形式储存,即使整数也是如此。
1 === 1.0 // true
0.1 + 0.2 === 0.3 // false
0.3 / 0.1 // 2.9999999999999996
(0.3 - 0.2) === (0.2 - 0.1) // false
- js中,注意,对于var命令来说,局部变量只能在函数内部声明,在其他区块中声明,一律都是全局变量。
- js中,函数本身也是一个值,也有自己的作用域。它的作用域与变量一样,就是其声明时所在的作用域,与其运行时所在的作用域无关。
var a = 1;
var x = function () {
console.log(a);
};
function f() {
var a = 2;
x();
}
f() // 1
- 闭包
闭包的最大用处有两个,一个是可以读取外层函数内部的变量,另一个就是让这些变量始终保持在内存中,即闭包可以使得它诞生环境一直存在。
注意**,外层函数每次运行,都会生成一个新的闭包,而这个闭包又会保留外层函数的内部变量,所以内存消耗很大。**因此不能滥用闭包,否则会造成网页的性能问题。 - js中,值得注意的是,由于数组本质上是一种对象,所以可以为数组添加属性,但是这不影响length属性的值。
var a = [];
a['p'] = 'abc';
a.length // 0
a['p'] //abc
a[2.1] = '123';
a.length // 0
a[2.1] // 123
- “异或运算”有一个特殊运用,连续对两个数a和b进行三次异或运算,a^=b; b^=a; a^=b;,可以互换它们的值。这意味着,使用“异或运算”可以在不引入临时变量的前提下,互换两个变量的值。
var a = 10;
var b = 99;
a ^= b, b ^= a, a ^= b;
a // 99
b // 10
- js中,注意,一旦定义了取值函数get(或存值函数set),就不能将writable属性设为true,或者同时定义value属性,否则会报错。
var obj = {
};
Object.defineProperty(obj, 'p', {
value: 123,
get: function() {
return 456; }
});
// TypeError: Invalid property.
// A property cannot both have accessors and be writable or have a value
Object.defineProperty(obj, 'p', {
writable: true,
get: function() {
return 456; }
});
// TypeError: Invalid property descriptor.
// Cannot both specify accessors and a value or writable attribute
上面代码中,同时定义了get属性和value属性,以及将writable属性设为true,就会报错。
- Number() 、String()、 Boolean()
var v1 = new Number(123);
var v2 = new String('abc');
var v3 = new Boolean(true);
typeof v1 // "object"
typeof v2 // "object"
typeof v3 // "object"
v1 === 123 // false
v2 === 'abc' // false
v3 === true // false
// 字符串转为数值
Number('123') // 123
// 数值转为字符串
String(123) // "123"
// 数值转为布尔值
Boolean(123) // true
总结一下,这三个对象作为构造函数使用(带有new)时,可以将原始类型的值转为对象;作为普通函数使用时(不带有new),可以将任意类型的值,转为原始类型的值。
- 对象实例的hasOwnProperty方法返回一个布尔值,用于判断某个属性定义在对象自身,还是定义在原型链上。
Date.hasOwnProperty('length') // true
Date.hasOwnProperty('toString') // false
上面代码表明,Date.length(构造函数Date可以接受多少个参数)是Date自身的属性,Date.toString是继承的属性。
另外,hasOwnProperty方法是 JavaScript 之中唯一一个处理对象属性时,不会遍历原型链的方法。
- Promise 的回调函数不是正常的异步任务,而是微任务(microtask)。它们的区别在于,正常任务追加到下一轮事件循环**,微任务追加到本轮事件循环。这意味着,微任务的执行时间一定早于正常的异步任务。**
setTimeout(function() {
console.log(1);
}, 0);
new Promise(function (resolve, reject) {
resolve(2);
}).then(console.log);
console.log(3);
// 3
// 2
// 1
上面代码的输出结果是321。这说明then的回调函数的执行时间,早于setTimeout(fn, 0)。因为then是本轮事件循环执行,setTimeout(fn, 0)在下一轮事件循环开始时执行。