重学前端 第二章 js(上)
js类型
Undefined、Null、Boolean、String、Number、Symbol、Object
Undefined、Null
一般用全局变量undefined表示这个值,或者void运算把任意一个表达式变成undefined值。js中undefined是一个变量,而非关键字。Null表示定义了但是为空。在实际编程中,一般不会把变量赋值为undefined,这样可以保证undefined的变量都是从未赋值的自然状态。null是一个关键字。编码规范中,一般用void 0 代替undefined。
String
字符串的操作charAt、charCodeAt、length等方法针对的是UTF16编码。字符串的最大长度是及受字符串的编码长度影响。
Number
符合IEEE规定的双精度浮点数规则。
额外语言场景:1)NaN,占用了9007199254740990;2)Infinity,无穷大;3)-Infinity,负无穷大;4)js中要区分+0和-0,除法时除以-0,会得到负无穷大。
根据双精度浮点数的定义,非整数的Number类型无法用==来比较。
0.1+0.2 == 0.3 为false,精度丢失。
Number、String、Boolean跟new搭配时,产生对象。直接调用时,代表强制转换。
类型转换
1.多数情况下,Number是比parseInt和parseFloat更好的选择。
2.装箱转换:把基本类型转换为对应的对象。
规范类型
1)List和Record:用于描述函数传参过程
2)Set:主要用于解释字符集等
3)Completion Record:用于描述异常、跳出等语句执行过程
4)Reference:用于描述对象的属性
5)Property Descriptor:用于描述对象的属性
6)Lexical Environment和Environment Record:用于描述变量和作用域。
7)Data Block:用于描述二进制数据
注:null ,typeOf时为object,运行时类型为Null
对象
为什么js没有类?
为什么js对象可以自由添加属性,而其他语言却不能
js中,使用者可以在运行时为对象添改状态和行为。
js的数据属性和访问器属性
1.数据属性
1)value:属性值
2)writable:决定属性能否被赋值
3)enumerable:决定for in能否枚举该属性
4)configurable:决定该属性能否被删除或改变特征值。
2.访问器属性
1)getter:函数或undefined,在取属性值时被调用
2)setter:函数或undefined,在设置属性值时被调用
3)enumerable:决定for in能否枚举该属性
4)configurable:决定该属性能否被删除或改变特征值。
原型
原型系统的“复制操作”有两种实现思路:
1)一个是并不真的去复制一个原型对象,而是使得新对象持有一个原型的引用;
2)另一个是切实地复制对象,从此两个对象再无关联。
js的原型:
1)如果所有对象都有私有字段,就是对象的原型。
2)读一个属性,如果对象本身没有,则继续访问对象的原型,直到原型为空或者找到为止。
es6之后,原型的内置函数:
1)Object.create根据指定的原型创建新对象,原型可以是null
2)Object.getPrototypeOf获得一个对象的原型
3)Object.setPrototypeOf设置一个对象的原型
3.
1)通过在构造器中修改this,给this添加属性
2)修改构造器的prototype属性指向的对象,它是从这个构造器构造出所有对象的原型。
对象的分类
1)宿主对象:由JavaScript宿主环境提供的对象,行为由宿主环境决定。
2)内置对象:由JavaScript语言提供的对象。(固有对象:由标准规定,随着JavaScript运行时创建而创建的对象实例;原生对象:由用户通过Array、RegExp等内置构造器或特殊语法创建的对象;普通对象:由{}语法、Object构造器或者class关键字定义类创建的对象,它能够被原型继承)
用对象模拟函数与构造器:
函数对象:具有call私有字段的对象,构造器对象:具有construct私有字段的对象
JavaScript用对象模拟函数的设计代替了一般编程语言中的函数,可以像其他语言的函数一样被调用、传参。任何宿主只要提供了“具有call私有字段的对象”,就可以被JavaScript函数调用语法支持。
对于宿主和内置对象,实现call和construct不总是一致。例如,内置对象Date和浏览器宿主对象Image。
es6之后箭头函数创建的只是函数,无法被当作构造器使用;function语法或者Function构造器创建的对象来说,call和construct行为总是相似的,执行同一段代码。
以Object.prototype为原型创建一个新对象;以新对象为this,执行函数的call;如果call的返回值时对象,那么,返回这个对象,否则返回第一步创建的新对象;
特殊对象:
Array:length属性根据最大下标自动发生变化;
Object.prototype:作为所有正常对象的默认原型,不能再给他设置原型了。
String:为了支持下标运算,String的正整数属性访问会去字符串里查找
Arguments:arguments的非负整数型下标属性跟对应的变量联动。
模块的namespace对象:特殊的地方非常多,跟一般对象完全不一样,尽量只用于import
类型数组和数组缓冲区:跟内存块相关联,下标运算比较特殊。
bind后的function:跟原来的函数相关联。