变量类型和计算

值类型

String Number Boolen Symbol (符号) Undefined 保存在栈中,占据固定空间
JS基础 - 图1
执行一个方法时,每个方法会创建自己的内存栈,执行结束后内存栈会自行销毁。

引用类型

Object Array null(null 是特殊的引用类型,指针指向空地址) 值保存在堆中,栈中保存内存地址(指针)。
函数(函数是一种特殊的引用类型,但是不能用作储存数据,所以没有拷贝克隆一说)
JS基础 - 图2
堆中的value不会随着方法执行结束而销毁,因为这个这个vlaue还被其他变量引用,只有当value不再被任何比变量引用时,才会被销毁。

typeof

typeof能识别所有的值类型 String Number Boolean Symbol undefined

typeof识别函数 function

  1. typeof(console.log) //function

typeof识别引用类型(不会细分)把array null object都识别为object

  1. typeof([]) //object
  2. typeof(null) //object

字符串拼接

  1. const a = 100 + 10; // 110
  2. const b = 100 + `10`; // '10010' 遇到字符串全转为字符串
  3. const c = true + `10`; // 'true10'

==

==是不严格相等,在比较过程 类型相同时比较大小 ,类型不同会先将比较数进行强制类型转化,在进行值比较

  1. 0 == ''// true
  2. 0 == false// true
  3. 1 == true //true
  4. 2 == true //false
  5. null == 0 //false
  6. null = false //false
  7. false == ''// true
  8. null == undefined // true
  9. // 除了== null之外 其他都用===
  10. const obj = {a: 100}
  11. if(obj.a == null){} // 相当于if(obj.a===null||obj.a===undefined){}

类型转换

  • 如果任一操作数是布尔型,会转换成数值,false转换为0;true转换为1
  • 如果是数字和字符串,会尝试将字符串转为数字,再比较相等
  • 如果一个操作数是对象,另一个不是,则调用对象的valueOf()方法取得原始值,再根据前面的规则比较
  • 如果任一操作数是NaN,== 始终返回false !=始终返回true
  • null == undefined //true
  • null和undefined 不能转换成其他类型值进行比较
  • 如果两个操作数都是对象,则比较他们是不是同一个对象。

if语句和逻辑运算

truly变量 !!a === true的变量
falsely变量 !!a === false的变量

  1. // 以下是falsely变量 除此之外都是truly变量
  2. !!false === false
  3. !!'' === false
  4. !!undefined === false
  5. !!null === false
  6. !!NaN === false
  7. !!0=== false
  8. // truly 变量
  9. const a = true
  10. if(a){}
  11. const b = 100
  12. if(b){}
  13. // falsely变量
  14. const c = ''
  15. if(c){}
  16. const d = null
  17. if(d){}
  18. let e
  19. if(e){}

变量类型判断

typeof
typeof 判断一些复杂数据类型时会统一返回object

  1. typeof 'a' //string
  2. typeof 1 //number
  3. typeof NaN //number
  4. typeof null //object
  5. typeof undefined //undefined
  6. typeof {} //object
  7. typeof [] //object
  8. typeof function(){} //function
  9. typeof class a{} //function

使用typeof 判断NaN会返回Number;
使用typeof判断null,数组和对象时都会判断为Object
typeof可以用来判断String undefined

instanceof

引用值也称作对象(object),在js中除了原始类型之外的值都是引用类型,有这么几种内置的引用类型:Object,Array,Date,Error,RegExp。使用typeof运算符都会返回’object’.
instanceof一般用来判断引用类型数据 ,比如

  1. num instanceof Number, // false
  2. str instanceof String, // false
  3. bool instanceof Boolean, // false
  4. arr instanceof Array, // true
  5. new Date() instanceof Date, // true
  6. reg instanceof RegExp, // true
  7. arr instanceof Object, // true--注意
  8. new Date() instanceof Object // true--注意
  9. obj instanceof Object, // true--注意

从结果可以看出instanceof不能判断值类型,但是引用类型可以,值得注意的是内置的引用类型在instanceof Object的时候的值都是true,这就导致判断是对象时不准确

constructor

  1. bool.constructor === Boolean;// true
  2. num.constructor === Number;// true
  3. str.constructor === String ;// true
  4. arr.constructor === Array ;// true
  5. obj.constructor === Object ;// true
  6. fun.constructor === Function ;// true
  7. Symbol.constructor === Symbol ;// true

undefined和null没有contructor属性
constructor不能判断undefined和null,并且使用它是不安全的,因为contructor的指向是可以改变的

Object.prototype.toString

在任何值上调用 Object 原生的 toString() 方法,都会返回一个 [object NativeConstructorName] 格式的字符串。

  1. function foo(){};
  2. Object.prototype.toString.call(1); '[object Number]'
  3. Object.prototype.toString.call(NaN); '[object Number]'
  4. Object.prototype.toString.call('1'); '[object String]'
  5. Object.prototype.toString.call(true); '[object Boolean]'
  6. Object.prototype.toString.call(undefined); '[object Undefined]'
  7. Object.prototype.toString.call(null); '[object Null]'
  8. Object.prototype.toString.call(Symbol());'[object Symbol]'
  9. Object.prototype.toString.call(foo); '[object Function]'
  10. Object.prototype.toString.call([1,2,3]); '[object Array]'
  11. Object.prototype.toString.call({});'[object Object]'

判断是否是数组
Array.isArray()
用于确定传递的值是否是一个Array。如果对象是Array,则返回true,否则为false。

  1. Array.isArray([1, 2, 3]);
  2. // true
  3. Array.isArray({foo: 123});
  4. // false
  5. Array.isArray("foobar");
  6. // false
  7. Array.isArray(undefined);

type of和instance of原理

type of 返回数据类型, instance of 返回布尔值
type of能准确判断基本数据类型(null除外),但是判断引用数据类型会出错
instance of能判断引用数据类型,但不能判断基本数据类型

type of :js储存变量的时候会在机器码低位储存类型信息。 对象机器码类型信息是000;null 机器码类型信息是0,typeof null会被视作对象。
instanceof 主要的实现原理就是只要右边变量的 prototype 在左边变量的原型链上即可

class类

class基本语法

JavaScript中创建实例对象的传统方法是通过构造函数,例如:

  1. function Point(x,y){
  2. this.x = x
  3. this.y = y
  4. }
  5. Point.prototype.toStr = function(){
  6. return `${this.x}------${this.y}`
  7. }
  8. var pt = new Point(1,2)

在ES6中引入来Class类的概念,作为对象的模版。通过class关键字可以定义类。
class可以看作只是一个语法糖,它的功能ES5也能做到,新的class写法让对象原型更加清晰,也更面对对象编程。
将上面代码通过class写法就是:

  1. class Point1{
  2. constructor(x,y){
  3. this.x = x
  4. this.y = y
  5. }
  6. toStr(){
  7. return `${this.x}------${this.y}`
  8. }
  9. }
  10. var pt1 = new Point1(1,3)z

上面代码定义的类,里面的constructor方法,实际上就是构造方法 验证如下

  1. class Point1{
  2. constructor(x,y){
  3. this.x = x
  4. this.y = y
  5. }
  6. toStr(){
  7. return `${this.x}------${this.y}`
  8. }
  9. }
  10. Point1.prototype.constructor===Point1 // true

this关键字则代表实例对象
Point1类除了构造方法,还有一个toStr方法,定义该方法时前面不需要加function关键字,与构造方法之间也不需要逗号分隔。
es6的类,完全可以看作是构造函数另一种写法。

  1. class Point {
  2. // ...
  3. }
  4. typeof Point // "function"
  5. Point === Point.prototype.constructor // true

构造函数的prototype属性,在class类上仍然存在,类的方法实际上都是定义在prototype上的

  1. class Point{
  2. toStr(){
  3. //....
  4. }
  5. add(){
  6. //....
  7. }
  8. fixs(){
  9. //....
  10. }
  11. // ....
  12. }
  13. //等同于
  14. Point.prototype={
  15. toStr(){
  16. //....
  17. },
  18. add(){
  19. //....
  20. },
  21. fixs(){
  22. //....
  23. }
  24. }

因此,调用类上的方法,实际就是调用其原型上的方法

  1. class B{}
  2. let b = new B()
  3. b.constructor === B //true
  4. b.constructor === B.prototype.constructor//true

上述代码中,b是B类的实例,b的constructor方法就是B类原型上的constructor方法。

constructor方法

constructor方法是类的默认方法,在通过new创建一个实例时,会自动调用该方法。
一个类必须有constructor方法,如果该方法没有被显式创建,则默认添加一个空的constructor方法

  1. class Point{}
  2. //等同于
  3. class Point{
  4. constructor(){}
  5. }

上述代码中创建了一个空的类,JS会自动给其添加一个空的constructor方法,constructor方法默认返回实例对象(即this),完全可以指定成另外一个对象。

  1. class Foo{
  2. constructor(){
  3. return Object.creat(null)
  4. }
  5. }
  6. new Foo()instanceof Foo //false

如以上代码所示,在constructor中返回一个全新的对象,导致实例对象不是Foo的实例
与es5一样,实例的属性除非显式定义在this上,否则就是定义在原型上

  1. class Point{
  2. constructor(x,y){
  3. this.x = x
  4. this.y = y
  5. }
  6. toStr(){
  7. return `${this.x}----${this.y}`
  8. }
  9. }
  10. //hasOwnProperty:hasOwnProperty() 方法用来检测一个属性是否是对象的自有属性,而不是从原型链继承的
  11. let point = new Point(12,3)
  12. point.hasOwnProperty('x') // true
  13. point.hasOwnProperty('y') // true
  14. point.hasOwnProperty('toStr') // false
  15. point.__proto__ === Point.prototype //true
  16. point.__proto__.hasOwnProperty('toStr') // true

上面代码中x和y都是定义在this上属于point实例对象的自身属性,而toStr方法则是定义在Point类的原型上

与es5一样,所有的原型都共享一个原型对象 proto

  1. let point1 = new Point()
  2. let point2 = new Point()
  3. point1.__proto__ === point2.__proto__ //true

这也意味着,可以通过实例的proto属性为“类”添加方法。

对象遍历

for… in

不仅可以枚举自身属性,还可以枚举原型链上的属性

Object.keys()

返回一个对象自身可枚举属性的数组(不枚举原型链上的属性)

Object.values()

返回一个对象自身可枚举属性值的数组(不枚举原型链上的属性)

Object.entries()

返回给定对象自身可枚举属性的键值对数组(不枚举原型链上的属性)

  1. natureColors:{
  2. colorC:'green',
  3. colorD:'yellow'
  4. }
  5. Object.entries(natureColors);
  6. // => [ ['colorC', 'green'], ['colorD', 'yellow'] ]

Set 和 Map

Set

允许存任何类型的值,但是成员都是唯一的,不可重复。
Set 本身是一个构造函数,可以接收数组或者其他具有iterable接口的数据结构。
特殊值
Set加入值的时候,不会进行类型转换,所以5和‘5’是不重复的,判断依据类似与’===’,但是也有一些特殊值

  • NaN === NaN //false 但是在Set中,看作重复值,只能出现一次
  • 空对象可以出现多次。

方法

  • has(value):返回布尔值,是否有某元素
  • add(value):添加某个值
  • delete(value):删除某个值
  • clear():清空

遍历方法

  • keys():返回键名的遍历器。
  • values():返回键值的遍历器。
  • entries():返回键值对的遍历器。
  • forEach():使用回调函数遍历每个成员。

可以使用for of遍历 keys(),values(),entires()

Map

保存键值对,任何值都可以为键或者值
Map和Object 区别

  • Map中的键值是有序的(FIFO 原则),而添加到对象中的键则不是。
  • Map的键值对个数可以从 size 属性获取,而 Object 的键值对个数只能手动计算。
  • Object 都有自己的原型,原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。

Map方法

  • set(key, val): 向Map中添加新元素
  • get(key): 通过键值查找特定的数值并返回
  • has(key): 判断Map对象中是否有Key所对应的值,有返回true,否则返回false
  • delete(key): 通过键值从Map中移除对应的数据
  • clear(): 将这个Map中的所有元素删除


遍历方法

  • keys():返回键名的遍历器
  • values():返回键值的遍历器
  • entries():返回键值对的遍历器
  • forEach():使用回调函数遍历每个成员

可以使用for of遍历 keys(),values(),entires()

数组

总结资料

箭头函数

总结资料