前端工程师吃饭的家伙——javaScript基础①变量和类型

本文部分内容来源:https://mp.weixin.qq.com/s/A8YyeM2N2MP23gEMzVLeswhttps://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中,栈中可以存放值类型、引用类型对象的地址、执行上下文(最底层永远是全局上下文)等等,堆中则存放引用类型对象。

 

  基本类型的内置对象有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

 

posted @ 2019-12-09 16:31  菜菜入锅  阅读(243)  评论(0编辑  收藏  举报