前端工程师吃饭的家伙——javaScript基础①变量和类型
本文部分内容来源:https://mp.weixin.qq.com/s/A8YyeM2N2MP23gEMzVLesw,https://www.cnblogs.com/cider/p/11875832.html
知识体系的自检清单:
一、JavaScript基础
变量和类型
-
1.
JavaScript
规定了几种语言类型
七种类型:boolean string number undefined null symbol object
其中可以分为两大类:基本数据类型(Boolean String Number Undefined Null Symbol)和引用类型(Object:Object Array Function RegExp Date null)
注意: null 是值类型,但是是一个空的对象引用,typeof null => object
symbol是ES6引入的一种新的原始数据,表示独一无二且不可改变的值。通过 Symbol 函数调用生成,由于生成的 symbol 值为原始类型,所以 Symbol 函数不能使用 new 调用,更多了解https://zhuanlan.zhihu.com/p/22652486
值类型不是由内置函数new出来的,尽管他们有对应的引用类型
值类型复制的是值,直接保存在栈中,引用类型复制的是栈里面指向堆中对象的地址,真正的对象保存在堆内存中
-
2.
JavaScript
对象的底层数据结构是什么
数据在内存中的存储结构,也就是物理结构,分为两种:顺序存储结构和链式存储结构。
JavaScript数据结构:es5自带的:array、object;es6自带的:set map、weakset weakmap (强引用、弱引用,Set 和 Map 数据结构);es未有的:dictionary list linkedlist doublelinkedlist quene hash stack。在JavaScript中不管多么复杂的数据和代码,都可以组织成object形式的对象
V8里面所有的数据类型的根父类都是Object,Object派生HeapObject,提供存储基本功能,往下的JSReceiver用于原型查找,再往下的JSObject就是JS里面的Object,Array/Function/Date等继承于JSObject。FixedArray是实际存储数据的地方。再谈js对象数据结构底层实现原理-object array map set
-
3.
Symbol
类型在实际开发中的应用、可手动实现一个简单的Symbol
Symbol调用方式,只能是Symbol(),且会生成唯一值,typeof symbol1 => symbol,console.log(symbol1) => Symbol(),作为属性名的时候要用中括号
使用Symbol.for(key)可以为字符串和 Symbol 提供一对一的关系,此时只要key相同,变量就对应同一个symbol
消除魔法字符串(与代码形成强耦合的字符串)https://www.jianshu.com/p/71a35da05102
1 const shapeType = {
2 triangle: Symbol(),
3 rectangular: Symbol()
4 };
5
6 function getArea(shape, options) {
7 let area = 0;
8 switch (shape) {
9 case shapeType.triangle:
10 area = .5 * options.width * options.height;
11 break;
12 case shapeType.rectangular:
13 area = options.width * options.height;
14 break;
15 }
16 return area;
17 }
18
19 getArea(shapeType.triangle, { width: 100, height: 100 });
用作私有变量 https://my.oschina.net/u/2903254/blog/818796
1 let Square = (function() {
2
3 const _width = Symbol('width');
4
5 class Square {
6 constructor( width0 ) {
7 this[_width] = width0;
8 }
9 getWidth() {
10 return this[_width];
11 }
12 }
13
14 return Square;
15
16 } )();
-
4.
JavaScript
中的变量在内存中的具体存储形式
一篇比较完整有深度的堆栈理解文章:https://www.jianshu.com/p/52b5a1879aa1
运行时内存中有堆栈两个用于存储变量的地方:
栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。操作方式类似于数据结构中的栈。
堆(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式类似于链表。
在Javascript中,栈中可以存放值类型、引用类型对象的地址、执行上下文(最底层永远是全局上下文)等等,堆中则存放引用类型对象。
-
5.基本类型对应的内置对象,以及他们之间的装箱拆箱操作 https://www.cnblogs.com/suihang/p/10606693.html
基本类型的内置对象有3个:Boolean、String、Number。每当读取一个基本类型值的时候,后台会创建一个对应的基本包装类型的对象,从而能够调用一些方法来操作这些基本类型。每个包装类型都映射到同名的基本类型。
装箱就是把基本类型转换为对应的内置对象,这里可分为隐式和显式装箱。拆箱就是把对象转变为基本类型。
隐式装箱:var str="abc"; str.slice(1) 像这种定义了一个string类型,它是不会有slice方法的,但是程序会隐式的创建一个string类型对应的基本包装类型对象 new String(“abc”),执行完毕后会立即摧毁这个包装对象。步骤:
(1)创建String类型的一个实例;
(2)在实例上调用指定的方法;
(3)销毁这个实例;
显示装箱:直接通过new调用Boolean、Number、String来创建基本包装类型的对象:new Number(2),new Boolean(),new String(),一般不会这么做。
拆箱:将引用类型转换为对应的值类型。通过引用类型的 valueOf() 或者 toString() 方法来实现。
-
6.理解值类型和引用类型
值类型和引用类型在第一点和第四点有提到,可以看到它们在内存分配时的机制不同,这一不同就导致了一些区别的产生。
1) 声明变量时的内存分配
值类型是存储在栈中的简单数据段,存储的位置上就放着本身的值,它们占据的空间固定,放在栈中便于查找。
引用类型是存储在堆中的对象,栈中也会同时产生一块区域存放这个对象的地址,由于引用类型对象的大小会变化,如果直接将对象放在栈中会影响栈存储空间的分配
2) 访问机制
值类型可以直接访问
引用类型要通过寻址才能获取对象的值
3) 复制
基本类型复制出的变量有独立的内存空间,互不相干。
引用类型复制会将栈中存储的地址给到新变量,此时,两个变量在栈中各有一个内存空间,而且都指向堆中的一个对象。两个变量的变化相互影响。
4) 参数传递
基本类型作为参数传递时只是把值传给函数,参数在函数中被改变并不会对原来的变量产生影响。
引用类型作为参数传递会将内存地址传入,参数在函数中被改变就是改变了这个地址指向的对象,那么原来的变量的值也会改变。
-
7.
null
和undefined
的区别
null是一个空的对象引用,undefined是值类型初始化时未赋值
-
8.至少可以说出三种判断
JavaScript
数据类型的方式,以及他们的优缺点,如何准确的判断数组类型
5种常用的方法,分别是typeof、instanceof、Object.prototype.toString()、constructor、jquery的type()
typeof:可以检测基本类型,但是引用类型除了function其他的不能区分
instanceof:判断已知对象的类型,如果用来判断基本类型,则始终返回false
Object.prototype.toString():该方法本质是利用Object.prototype.toString()方法得到对象内部属性[[Class]],传入基本类型也能够判断出结果是因为对其值做了包装。
constructor
jQuery.type()
如何准确的判断数组类型?
-
9.可能发生隐式类型转换的场景以及转换原则,应如何避免或巧妙应用
+:+ 号操作时,数字被隐式转换成字符串,实际上做的是字符串连接操作。做除了加法以外的运算操作时,字符串被隐式转换成数字,实际上做的是数值计算。
. 点:数字、字符串等基本类型在调用方法时,隐式地将类型转换成对象。
if:If()括号里的表达式部分会被隐式转化为布尔类型进行判别。
==:等号左右两边会被转化为同一种类型再进行比较
-
10.出现小数精度丢失的原因,
JavaScript
可以存储的最大数字、最大安全数字,JavaScript
处理大数字的方法、避免精度丢失的方法
看似有穷的数字, 在计算机的二进制表示里却是无穷的,由于存储位数限制因此存在“舍去”,精度丢失就发生了
JavaScript
可以存储的最大数字:,最大安全数字:
。JS 中能精准表示的最大整数是 Math.pow(2, 53),即最大安全数字。
JavaScript
处理大数字的方法、避免精度丢失的方法:看这篇文章吧~https://www.cnblogs.com/snandy/p/4943138.html