Js基础知识7-Es6新增对象Map和set数据结构

前言

JavaScript中对象的本质是键值对的集合,ES5中的数据结构,主要是用Array和Object,但是键只能是字符串。为了弥补这种缺憾,ES6带来了一种新的数据结构Map。

Map也是键值对的集合,只是键不仅可以是字符串还可以是其他数据类型,比如:对象(是不是很神奇)。请看下面例子。。下面话不多说了,来一起看看详细的介绍吧。

Map 对象

Map结构提供了“值—值”的对应,任何值(对象或者原始值) 都可以作为一个键或一个值,是一种更完善的Hash结构实现。如果你需要“键值对”的数据结构,Map比Object更合适。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。

属性

Map属性

  • Map.length 属性length的值为0。
  • Map.prototype 表示Map构造器的原型。允许添加属性从而应用与所有的Map对象

Map实例 - 所有Map对象的实例都会继承Map.prototype。

  • Map.prototype.constructor 返回创建给map实例的构造函数,默认是Map函数。
  • Map.prototype.size 返回Map对象的键值对的数量。
    var map = new Map([[‘one‘,1], [‘two‘, 2], [‘three‘, 3]]);
    console.log(map.constructor); //function Map() { [native code] }
    console.log(map.size); //3

方法

    //Iterator对象:可以使用for..of进行迭代的对象
    var map = new Map([[1, ‘one‘],[2, ‘two‘], [3, ‘three‘]]);

1.Map.prototype.set(key, value) 设置Map对象中键的值,返回该Map对象。

    console.log(map.has(4));    //false
    map.set(4, ‘four‘);
    console.log(map.has(4))    //true

2.Map.prototype.get(key) 返回键对应的值,如果不存在,则返回undefined。

    map.get(1); //‘one‘

3.Map.prototype.has(key) 返回一个布尔值,表示Map实例是否包含键对应的值。

    map.has(1); // true
    map.has(5); //false

4.Map.prototype.delete(key) 移除任何与键相关联的值,并且返回该值,该值在之前会被Map.prototype.has(key)返回为true。之后再调用则返回false。

    console.log(map.has(1));    //true
    map.delete(1);
    console.log(map.has(1));    //false

5.Map.prototype.clear() 移除Map对象的所有键值对。

    console.log(map.size);    //3
    map.clear();
    console.log(map.size);    //0

6.Map.prototype.entries() 返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的[key, value]数组。

    console.log(map);    //Map {1 => "one", 2 => "two", 3 => "three"}
    map.entries();
    console.log(map);    //Map {1 => "one", 2 => "two", 3 => "three"}

7.Map.prototype.forEach(callbackFn[, thisArg]) 按插入顺序,为Map对象里的每一键值对调用一次callbackFn函数。如果为forEach提供了thisArg,他将在每次回调函数中作为this值。

    map.forEach(function(value, key, mapObj) {
        console.log(value + ‘---‘ + key + ‘---‘ + mapObj);
        //value - Map对象里每一个键值对的值
        //key - Map对象里每一个键值对的键
        //mapObj - Map对象本身
        console.log(this); //this === window
    });

    map.forEach(function(value, key, mapObj) {
        console.log(value + ‘---‘ + key + ‘---‘ + mapObj);
        console.log(this);    //this === map
    }, map)

8.Map.prototype.keys() 返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的键。

    map.keys();    //MapIterator {1, 2, 3}

9.Map.prototype.values() 返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的值。

    map.values(); //

使用for..of方法迭代映射

    var map = new Map();
    map.set(1, ‘one‘);
    map.set(2, ‘two‘);
    for (var [key, value] of map) {
        console.log(key + ‘---‘ + value);
    }
    // 1 --- one 2 --- two

    for (var key of map.keys()) {
        console.log(key);
    }
    // 1 2

    for (var value of map.values()) {
        console.log(value);
    }
    // ‘one‘ ‘two‘

常规用法综合

var map = new Map();  //创建map对象
map.set(‘one‘, 1);
map.set(‘two‘, 2);
map.set(‘three‘, 3);
//或者   var map = new Map([[‘one‘,1], [‘two‘, 2], [‘three‘, 3]]);

m.set(ul,‘content‘); //为Map增加成员
m.get(ul);//获取键 ul对应的值
m.has(ul);//返回布尔值,判断是否含有键 ul
m.delete(ul);//删除键 ul,成功返回true,失败返回false
m.size //返回m长度
m.clear(); //清除m所有成员

Map VS Object

  • 一个对象通常都有自己的原型,所以一个对象总有一个"prototype"键。不过,从ES5开始可以使用map = Object.create(null)来创建一个没有原型的对象。
  • 一个对象的键只能是字符串或者Symbols,但一个Map的键可以是任意值。
  • 你可以通过size属性很容易地得到一个Map的键值对个数,而对象的键值对个数只能手动确认。

数据类型转换

...扩展语句

扩展语法允许一个表达式在期望多个参数(用于函数调用)或多个元素(用于数组字面量)或多个变量(用于解构赋值)的位置扩展。

let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];
arr1 = [...arr2, ...arr1];
console.log(arr1) // [3, 4, 5, 0, 1, 2]

Map转数据的最简单方式是使用 ... 扩展运算符。例如:

var map = new Map([[‘one‘,1], [‘two‘, 2], [‘three‘, 3]]);
console.log(...map);  //["one", 1]   ["two", 2]   ["three", 3]

Map转对象时,必须所有键都是字符串,使用Object.create()函数。Map转JSON时,要求也要求所有键都是字符串,使用JSON.Stringify()函数。

需要注意的

1、转换时注意

2、当键是对象时,必须是引用相同,才认为键是相同的。只有对同一个对象的引用,Map结构才将其视为同一个键。这一点要非常小心。

var map = new Map();
map.set([‘a‘], 555);
map.get([‘a‘]) // undefined
//上面代码的set和get方法,表面是针对同一个键,但实际上这是两个值,内存地址是不一样的,因此get方法无法读取该键,返回undefined。

3、如果Map的键是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等,Map将其视为一个键,包括0和-0。另外,虽然NaN不严格相等于自身,但Map将其视为同一个键。

    var map = new Map();
    map.set(Number(‘aa111‘), ‘isNaN‘);
    map.set(Number(‘bb222‘), ‘also is NaN‘);
    map.get(NaN);    //‘also is NaN‘

Set 对象

简要

ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

Set函数可以接受一个数组(或类似数组的对象)作为参数,用来初始化。

Set对象允许你存储任意类型的唯一值(不能重复),无论它是原始值或者是对象引用。

Set本身是一个构造函数,用来生成Set数据结构。

Set结构有以下属性:

  • Set.prototype.constructor: 构造函数,默认就是Set函数。
  • set.prototype.size : 返回Set的成员总数。

Set结构有以下方法:

  • add(value) : 添加某个值,返回Set结构本身。
  • delete(value) : 删除某个值,返回一个布尔值,表示是否成功。
  • has(value) : 返回一个布尔值,表示该值是否为Set的成员。
  • clear() : 清除所有成员,没有返回值。

Set遍历操作:

  • keys():返回键名的遍历器
  • values(): 返回健值对的遍历器
  • entries():返回键值对的遍历器
  • forEach(): 每个成员

Set属性

  • Set.length 属性length的值为0。
  • Set.prototype 表示Set构造器的原型。允许向所有Set对象添加新的属性。

Set实例

所有Set对象的实例都会继承Set.prototype。

  • Set.prototype.constructor 返回创建给set实例的构造函数,默认是Set函数。
  • Set.prototype.size 返回Set对象的键值对的数量。
    var sset = new Set([‘one‘, ‘two‘, ‘three‘]);
    console.log(sset.constructor); //function Set() { [native code] }
    console.log(sset.size); //3

Set方法

    //创建Set实例
    //1.
    var sset = new Set();
    sset.add(‘one‘);
    sset.add(‘two‘);
    sset.add(‘three‘);
    //2.
    var sset= new Set([‘one‘, ‘two‘, ‘three‘]);

1.Set.prototype.add(value) 在Set对象尾部添加一个元素。返回该Set对象。

    sset.add(‘four‘);
    console.log(sset);    //Set {"one", "two", "three", "four"}

2.Set.prototype.clear() 移除Set对象内的所有元素。

    sset.clear();
    console.log(sset.size);    //0

3.Set.prototype.delete(value) 移除Set的中与这个值相等的元素,返回Set.prototype.has(value)在这个操作前会返回的值(即如果该元素存在,返回true,否则返回false)。Set.prototype.has(value)在此后会返回false。

    console.log(sset.has(‘one‘));    //true
    sset.delete(‘one‘);
    console.log(sset.has(‘one‘));    //false

4.Set.prototype.entries() 返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值的[value, value]数组。为了使这个方法和Map对象保持相似, 每个值的键和值相等。

5.Set.prototype.forEach(callbackFn[, thisArg]) 按照插入顺序,为Set对象中的每一个值调用一次callBackFn。如果提供了thisArg参数,回调中的this会是这个参数。

    sset.forEach(function(value, key, setObj) {
        console.log(value + ‘---‘ + key + ‘---‘ + setObj);
        //value - Set对象里每一个键值对的值
        //key - Set对象里每一个键值对的键 === 值
        //mapObj - Set对象本身
        console.log(this); //this === window
    });

    sset.forEach(function(value, key, setObj) {
        console.log(value + ‘---‘ + key + ‘---‘ + setObj);
        console.log(this);    //this === sset
    }, sset)

6.Set.prototype.has(value) 返回一个布尔值,表示Map实例是否包含键对应的值。

    sset.has(‘one‘); // true
    sset.has(‘fivr‘); //false

7.Set.prototype.keys() 与values()方法相同,返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值。

    sset.keys();    //SetIterator {"one", "two", "three"}

8.Set.prototype.values() 返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的值。

    sset.values(); //SetIterator {"one", "two", "three"}

使用for..of方法迭代映射

    var sset = new Set();
    sset.add(1);
    sset.add(2);
    for (var value of sset) {
        console.log(value);
    }
    // 1 2

    for (var key of sset.keys()) {
        console.log(key);
    }
    // 1 2

    for (var value of sset.values()) {
        console.log(value);
    }
    // 1 2

Set 与 Array

var myArray = ["value1", "value2", "value3"];

// 用Set构造器将Array转换为Set
var mySet = new Set(myArray);

mySet.has("value1"); // returns true

// 用...(展开操作符)操作符将Set转换为Array
console.log([...mySet]); // 与myArray完全一致

Array.from方法可以将Set结构转换为数组。

var items = new Set([1, 2, 3, 4, 5]);
var array = Array.from( items );

这也提供了一种除去数组中重复元素的方法。

function dedupe( array ) {
    return Array.from( new Set(array) );
}

或者如下写也可以,比较简单的数组去重

[...new Set([1,3,4,5,1,2,3,3,4,8,90,3,0,5,4,0])]

Set 注意

1、var sset = new Set(‘one‘, ‘two‘, ‘three‘);  //这样的错误的

2、值的相等规则:NaN 是与NaN是相同的(虽然NaN !== NaN),除此之外所有的值都根据‘===‘判断。

    var sset= new Set();
    sset.add(Number(‘aa111‘));
    sset.add(Number(‘bb222‘));
    sset.add(‘cc333‘));
    //Set {NaN, "cc333"}

3、向Set加入值的时候,不会发生类型转换。这意味着,在Set中5和”5”是两个不同的值。

weakset对象

WeakSet结构与Set类似,也是不重复的值的集合。

WeakSet和Set的区别:

  • 1.WeakSet的成员只能是对象,而不能是其他类型的值
  • 2.WeakSet中的对象都是弱引用,即垃圾回收机制不考虑WeakSet对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于WeakSet之中。这个特点意味着,无法引用WeakSet的成员,因此WeakSet是不可遍历的。

WeakSet结构的三个方法
add
delete
has
WeakSet的一个用处是储存DOM节点,而不用担心这些节点会从文档中移除时,会引发内存泄露。

原文地址:https://www.cnblogs.com/7qin/p/9629501.html

时间: 2024-11-29 03:41:40

Js基础知识7-Es6新增对象Map和set数据结构的相关文章

Js基础知识1-对象、对象属性全解

Object对象 Object对象包含如下属性和方法,也就意味着一切对象(函数也是对象)都包含如下方法. 每种方法和属性在不同的对象中有不同的作用,并不是每种对象都有使用每个方法的必要. 下面是Object对象的派生对象在使用这些方法和属性时的意义.Object对象只是定义了他们,并没有使用他们. __proto__属性是保存当前对象的原型对象.对象通过这个属性产生了原型链,可以参考http://blog.csdn.net/luanpeng825485697/article/details/78

js 基础知识 对象与数组

对象是一种无序属性的集合,每个属性都有自己的名字和值. 对象的创建有很多种,我在第一章已经说过了. 如何遍历一个对象: var x;var txt="";var person={fname:"Bill",lname:"Gates",age:56}; for (x in person)       //x其实是一个变量,代表的是person对象的属性{txt=txt + person[x];              //person[属性]  等

JS基础知识回顾:引用类型(一)

在ECMAScript中引用类型是一种数据结构,用于将数据和功能组织在一起,而对象时引用类型的一个实例. 尽管ECMAScript从技术上讲是一门面向对象的语言,但它不具备传统的面向对象语言所支持的类和接口等基本结构,所以虽然说引用类型与类看起来想死,但他们并不是相同的概念. 不过引用类型有的时候也可以被称为对象定义,因为他们描述的是一类对象所具有的属性和方法. 新对象是使用new操作符后跟一个构造函数来实现的,构造函数本身就是一个函数,只不过该函数时处于创建新对象的目的而定义的. ECMASc

JS基础知识大全

JS基础知识 基本语法*switch循环(设置表达式 x(通常是一个变量) 随后表达式的值会与结构中的每个 case 的值做比较.如果存在匹配,则与该 case 关联的代码块会被执行.请使用 break 来阻止代码自动地向下一个 case 运行) 不进行类型转换 var x; switch(x){ case true:console.log("x类型转换") ; default:console.log("x没有发生类型转换"); }//case没有发生类型转换 sw

JS基础知识回顾:ECMAScript的语法(一)

任何语言的核心都必然会描述这门语言最基本的工作原理,而描述的内容通常都要涉及这门语言的语法.操作符.数据类型.内置功能等用于构建复杂解决方案的基本概念. ECMAScript中的一切变量.函数名.操作符都区分大小写. ECMAScript的标识符要符合下列规则:第一个字符必须是字母.下划线或美元符号:其他字符可以是字母.下划线.美元符号或数字. 标识符中的字母也可以包含扩展的ASCII或Unicode字母字符,但是并不推荐. 按照惯例,ECMAScript标识符采用驼峰大小写的格式来书写,尽管没

Node.js基础知识杂烩

Node.js基础知识杂烩 这段时间做项目主要做关于服务器的功能点,因此,逐渐开始学习node.js写服务器,总体下来,觉得node比php更好用,写服务前器的速度更快,处理效率更高.注:node并不是专门写服务器的,其实node的出现,将js从web前端的专用语言,变成了一门通用语言.node中有各样的基础模块:比如fs,path,buffer,http,net等模块,此外,node还有各种各样的三方模块,比如写服务器人常用的express,co,koa,seqlize等著名框架,也就是三方模

NodeJs>------->>第三章:Node.js基础知识

第三章:Node.js基础知识 一:Node.js中的控制台 1:console.log.console.info  方法 1 console.log("this is a test string."); 1 node app1.js 1> info.log 1 console.log("This is a test String ."); 2 3 //从第二个参数开始,依序输出所有的字符串 4 console.log("%s","

JS 基础知识4 运算符

JS的运算符一般含有: 1 算术运算符 2 相等运算符 3 关系运算符 4 字符串运算符 5逻辑运算符 6位运算符 7 赋值运算符 首先看算术运算符,它一般有(+,-,*,/,%,++,--) 这里,%模运算符,其实也就是取余的意思,比如,5%2=1: 这里要特别说一下++,与--(这里只列了++,--是一样的道理). 1 var i = 1; 2 var j = ++i; //实际相当于 i+=1;j=i; 3 alert(i + " " + j); 4 5 var m = 1; 6

JS 基础知识2 传值和传址

要知道传址跟传址,首先我们先了解下数据值的操作. 1复制:可以把它赋值给一个新的变量 2传递:可以将他传递给一个函数或者方法 3比较:可以与另外一个值比较,判断是否相等 简要介绍下传值: 当一个数据是通过值被操作的,那么关系到的是数据的值,在赋值的过程中,是对实际值进行了COPY,储存在一个变量或者属性或数组中,copy的值与原数据是相互独立的. 当数据通过值传递给一个函数时,数据的一份传递给这个函数,如果函数体修改了这个值,只在函数体受影响,函数外的原数据不受影响. 当一个数据通过值和另外一个