JavaScript知识点整理
整理了极客时间《重学前端》课程的JavaScript的重要知识点,当做复习和记录,里面很多内容参考了课程,确实非常非常好的一篇课程(未完待续…)
课程地址https://time.geekbang.org/column/intro/154
一、类型
1.1 七种基础类型
- Undefined
- Null
- Boolean
- String
- Number
- Symbol
- Object
1.2注意事项
undefined
undefined是个变量。还不是关键字,很容易被重新赋值,建议使用void 0代替
void 后面跟所有表达式返回都是undefined
几个特殊的数字
- NaN,占用了9007199254740990,这原本是符合IEEE规则的数字;
- Infinity, 无穷大;
- -Infinity, 负无穷大。
- js中是有+0 和 -0的
浮点数精度问题
错误的比较方式
console.log( 0.1 + 0.2 == 0.3);
正确的
console.log( Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON);
对象类型
Javascript中的几个基本类型,都在对象类型中有一个"亲戚"。它们是:
Number;
String.
Boolean;
Symbol,
但是 3 和 new Number(3) 是两个不同的东西。
3的类型是 Number但是 new Number(3)的类型是 对象类型
Number, String和Boolean,三个构造器是两用的,当跟new搭配时,它们产生对象,当直接调用时,它们表示强制类型转换。
装箱和拆箱操作
JavaScript语言设计上试图模糊对象和基本类型之间的关系,我们日常代码可以把对象的方法在基本类型上使用,比如:
console.log("abc".charAt(0)); //a
装箱
每一种基本类型Number, String, Boolean, Symbol在对象中都有对应的类,所谓装箱转换,正是把基本类型转换为对应的对象,它是类型转换中一种相当重要的种类。
拆箱
对象到String和Number的转换都遵循"先拆箱再转换"的规则。通过拆箱转换,把对象变成基本类型,再从基本类型转换为对应的String或者Number.
拆箱转换会尝试调用valueOf和toString来获得拆箱后的基本类型。
转到string 会先调用toString,相反会先调用valueOf,有一个返回了就不继续执行了,如果valueOf和toString都不存在,或者没有返回基本类型,则会产生类型错误TypeError.
var o = {
valueOf : () => {console.log("valueOf"); return {}},
toString : () => {console.log("toString"); return {}}
}
o * 2
// valueOf
// toString
// TypeError
Symbol.toPrimitive可以显式的定义拆箱
var o = {
valueOf : () => {console.log("valueOf"); return {}},
toString : () => {console.log("toString"); return {}}
}
o[Symbol.toPrimitive] = () => {console.log("toPrimitive"); return "hello"}
console.log(o + "")
// toPrimitive
// hello
二、JS的面向对象理解
2.1 JS如何完成对象特征的描述
对象的三个特征
- 唯一标识
- 状态
- 行为
唯一标识
跟其他语言一样,都是唯一的内存地址,即使两个长得一样的对象指向的也不是同一个对象
状态和行为。
JS里面状态和行为统一使用属性来描述
在JS里函数也是一种特殊的对象。JS语言通过对象来表达各种对象(包括对象,值还有方法)间组合,通讯的关系。
2.2 JS的两类属性
对JavaScript来说,属性并非只是简单的名称和值, Javascript用一组特征(attribute)来描述属性(property) .
数据属性
一般意义上的属性,标识和存储数据
- value:就是属性的值。
- writable:决定属性能否被赋值。
- enumerable:决定for in能否枚举该属性。
- configurable:决定该属性能否被删除或者改变特征值。
访问器属性
提供了属性的setter/getter方法。
- getter:函数或undefined,在取属性值时被调用。
- setter:函数或undefined,在设置属性值时被调用。
- enumerable:决定forin能否枚举该属性。
- configurable:决定该属性能否被删除或者改变特征值。
如何查看和设置这些属性的特征
使用Object.getOwnPropertyDescriptor
查看
var o = { a: 1 };
o.b = 2;
//a 和 b 皆为数据属性
Object.getOwnPropertyDescriptor(o,"a") // {value: 1, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor(o,"b") // {value: 2, writable: true, enumerable: true, configurable: true}
使用Object.defineProperty
设置
var o = { a: 1 };
Object.defineProperty(o, "b", {value: 2, writable: false, enumerable: false, configurable: true});
//a 和 b 都是数据属性,但特征值变化了
Object.getOwnPropertyDescriptor(o,"a"); // {value: 1, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor(o,"b"); // {value: 2, writable: false, enumerable: false, configurable: true}
o.b = 3;
console.log(o.b); // 2
2.3 JS–基于原型的面向对象
简单的原型系统可以用两条概括:
- 如果所有对象都有私有字段[[prototypel]],就是对象的原型;
- 读一个属性,如果对象本身没有,则会继续访问对象的原型,直到原型为空或者找到为止。
类和原型的关系
一开始类在JS中只是一个属性[[class]],一些语言标准的内置对象类型例如,Number、String、Data等指定[[class]]属性来表示类。只能使用Object.prototype.toString.call
访问
new的使用
new 这个关键字是针对构造器的,后面接受的是构造器和他的一组参数
new 干了什么
- 以构造器(一个function,只有function有prototype属性)的prototype为原型构造对象。
- this指向生成的那个对象。依据参数执行内容
- 如果构造器有返回值就返回,没有的话返回第一步生成的对象