重温JS——(ES6)内置对象(Map与Set、字符串、数值、对象、数组)

目录

内置对象

1、Map与Set

(1)Map

(2)Set

2、字符串

(1)子串的识别

(2)字符串重复

(3)字符串补全

(4)模板字符串

(5)标签模板

3、数值

(1)数值的表示

(2)方法

(3)Math对象的扩展

4、对象

(1)对象字面量

(2)对象的扩展运算符

(3)对象的新方法

5、数组

(1)数组创建

(2)扩展的方法

(3)扩展运算符(...)


ES5:5个基本数据类型:number boolean string null  undefined

ES6:新增1个基本数据类型:symbol  (独一无二的)它是一个内置全局函数,生成一个独一无二的数据

        var re = Symbol("hello")
        var re2 = Symbol("hello")
        console.log(re,re2,re == re2) //Symbol(hello) Symbol(hello) false
        console.log(typeof re)  //symbol
   

内置对象

浏览器提供的引用数据: document  window Image

ES5提供的: Date Math Array ReExp Object

ES6提供的: Map Set

1、Map与Set

(1)Map

Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。

Map没有语法糖,Map很像一个对象

Map特点:有序、键值对(键可以是任意类型)、键名不能重复(如果重复,那么覆盖)

  • Map和Object的区别

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

    • key是字符串

    var myMap = new Map();
    var keyString = "a string"; 
     
    myMap.set(keyString, "和键'a string'关联的值");
     
    myMap.get(keyString);    // "和键'a string'关联的值"
    myMap.get("a string");   // "和键'a string'关联的值"
                             // 因为 keyString === 'a string'
    • key是对象  (key是一个引用数据,所以需要用变量保存这个引用数据,才是取到了同一个引用,否则就是两个空间,就算写的和它一样,也不是一个空间,就会是und)

    var myMap = new Map();
    var keyObj = {}, 
     
    myMap.set(keyObj, "和键 keyObj 关联的值");
    ​
    myMap.get(keyObj); // "和键 keyObj 关联的值"
    myMap.get({}); // undefined, 因为 keyObj !== {}     //不是同一个空间
    • key是函数

    var myMap = new Map();
    var keyFunc = function () {}, // 函数
     
    myMap.set(keyFunc, "和键 keyObj 关联的值");
     
    myMap.get(keyFunc); // "和键 keyFunc 关联的值"
    myMap.get(function() {}) // undefined, 因为 keyFunc !== function () {}
    • key是NaN

            var myMap = new Map();
            myMap.set(NaN, "not a number");
            console.log(myMap.get(NaN))  // "not a number"
    
            var otherNaN = Number("foo");
            myMap.get(otherNaN); 
            console.log(myMap.get(otherNaN))  // "not a number"
    

             

  • Map的迭代:对Map进行遍历

    • for...of

    var myMap = new Map();
    myMap.set(0, "zero");
    myMap.set(1, "one");
     
    // 将会显示两个 log。 一个是 "0 = zero" 另一个是 "1 = one"
    //for...of遍历Map对象,取出每个键值对的键key和值value
    for (var [key, value] of myMap) {
      console.log(key + " = " + value);
    }
    ​
    /* 这个 entries 方法返回一个新的 Iterator 对象,它按插入顺序包含了 Map 对象中每个元素的 [key, value] 数组。 */
    for (var [key, value] of myMap.entries()) {
      console.log(key + " = " + value);
    }
     
    /* 这个 keys 方法返回一个新的 Iterator 对象, 它按插入顺序包含了 Map 对象中每个元素的键。 */
    for (var key of myMap.keys()) {
      console.log(key);
    }
    ​
    /* 这个 values 方法返回一个新的 Iterator 对象,它按插入顺序包含了 Map 对象中每个元素的值。 */
    for (var value of myMap.values()) {
      console.log(value);
    }
    • forEach()

            var myMap = new Map();
            myMap.set(0, "zero");
            myMap.set(1, "one");
            myMap.forEach(function (value, key) {
                console.log(key + " = " + value);
            }, myMap)     //0 = zero   1 = one

  • Map对象的操作

    • Map 与 Array的转换   

    • (数组==》转Map:直接将数组写在Map后面的括号里)  必须是二维数组

    • (Map==》转数组:使用静态函数  Array.from)

    var kvArray = [["key1", "value1"], ["key2", "value2"]]; //二维数组
     
    // Map 构造函数可以将一个 二维 键值对数组转换成一个 Map 对象
    var myMap = new Map(kvArray); 
    console.log(myMap); //Map(2) {"key1" => "value1", "key2" => "value2"}
     
    // 使用 Array.from 函数可以将一个 Map 对象转换成一个二维键值对数组
    var outArray = Array.from(myMap);
    console.log(outArray); //[["key1", "value1"], ["key2", "value2"]]
    • Map的克隆

    var myMap1 = new Map([["key1", "value1"], ["key2", "value2"]]);
    var myMap2 = new Map(myMap1);
     
    console.log(myMap1 === myMap2); 
    // 打印 false。 Map 对象构造函数生成实例,迭代出新的对象。
    • Map的合并

    var first = new Map([[1, 'one'], [2, 'two'], [3, 'three']]);
    var second = new Map([[1, 'uno'], [2, 'dos']]);
    // 合并两个 Map 对象时,如果有重复的键值,则后面的会覆盖前面的,对应值即 uno,dos, three
    var merged = new Map([...first, ...second]);
    console.log(merged)  //Map(3) {1 => 'uno', 2 => 'dos', 3 => 'three'}
    

    ...a  ==>  就是将一个数据容器(可以是 集合、Map、数组等)的元素全部取出来装在数组中

//没有创建的语法糖
			var a=["key"]
			var m1=new Map([["age",100],[20,"hello"],[["key"],90],[a,90]])//初始化

			//取数据get
			var re1=m1.get("age")
			var re2=m1.get(20)
			var re3=m1.get(["key"])   //因为["key"]是一个数组引用数据,这里取得不是上面得存储空间,所以需要用变量a将其保存起来
			var re4=m1.get(a)
			console.log(re1,re2,re3,re4)   //100 'hello' undefined 90

			//存数据set
			m1.set("life",1)//新增
			m1.set("age",1)//覆盖
			console.log(m1)  //Map(5) {'age' => 1, 20 => 'hello', Array(1) => 90, Array(1) => 90, 'life' => 1}
			console.log(m1.size)  //5

			//删除delete
			m1.delete(20)
			var re5=m1.delete("age")
			var re6=m1.delete("age")
			console.log(m1,re5,re6)  //Map(3) {Array(1) => 90, Array(1) => 90, 'life' => 1} true false

			//全部清空clear
			m1.clear()
			console.log(m1)  //Map(0) {size: 0}

购物车的设计:

			//现在没有页面设计  可以用打印代替
			//购物车
			//后端取出来的额数据 要先解析然后保存到前端的某个数据容器中
			var mycar = {
				data: new Map(),
				clear:function(){
					this.data.clear()
				},
				jianshao:function(id){
					let obj=this.data.get(id)
					if(obj){
						obj.count--
						if(obj.count<=0){
							this.data.delete(id)
						}
					}
				},
				add: function(id) {
					let obj = this.data.get(id)
					if (obj) {
						// console.log(obj)
						obj.count++
						this.data.set(id, obj)
					}
				},
				total: function() {
					var result = 0;
					this.data.forEach(function(el) {
						console.log(el)
						result += el.count * el.price
					})
					return result
				},
				network: function() {
					var jiashuju = [{
						id: 435123,
						title: "鱼香肉丝",
						price: 18,
						count: 1
					}, {
						id: 435124,
						title: "东坡肉",
						price: 28,
						count: 1
					}, {
						id: 435125,
						title: "米饭",
						price: 2,
						count: 2
					}];
					// this.data.set(jiashuju[0].id,jiashuju[0])
					// this.data.set(jiashuju[1].id,jiashuju[1])
					// this.data.set(jiashuju[2].id,jiashuju[2])
					var self = this
					jiashuju.map(function(el) {
						self.data.set(el.id, el)
					})
				}
			}
			mycar.network()
			mycar.add(435123)
			mycar.add(435125)
			mycar.add(435125)
			mycar.add(435125)
			mycar.add(435125)
			mycar.add(435125)
			mycar.jianshao(435124)
			console.log(mycar.data)
			var re1 = mycar.total()
			console.log(re1)
			mycar.clear()
			console.log(mycar.data)

(2)Set

Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。

set很像数组,它是一个集合。

Set集合和数组的区别:  1、Set集合不能重复元素 2、Set取数据不是用下标取,而是用遍历取  3、存数据用add()函数存,没有先后顺序   4、集合是size,数组是length

  • Set中的特殊值

    Set 对象存储的值总是唯一的,所以需要判断两个值是否恒等。有几个特殊值需要特殊对待:

    +0 与 -0 在存储判断唯一性的时候是恒等的,所以不重复;
    undefined 与 undefined 是恒等的,所以不重复;
    NaN 与 NaN 是不恒等的,但是在 Set 中只能存一个,不重复。
    
            let mySet = new Set();
            mySet.add(1); // Set(1) {1}
            mySet.add(5); // Set(2) {1, 5}
            mySet.add(5); // Set(2) {1, 5} 这里体现了值的唯一性
            mySet.add("some text"); 
            // Set(3) {1, 5, "some text"} 这里体现了类型的多样性
            var o = {a: 1, b: 2}; 
            mySet.add(o);
            mySet.add({a: 1, b: 2}); 
            // Set(5) {1, 5, "some text", {…}, {…}} 
            // 这里体现了对象之间引用不同不恒等,即使值相同,Set 也能存储
    
            //集合取数据,用forEach去遍历
            mySet.forEach(function(el) {
                console.log(el)
            })  //1  5   some text   {a: 1, b: 2}   {a: 1, b: 2}
    

  • 类型转换

    • Array

            // Array 转 Set
            var mySet = new Set(["value1", "value2", "value3"]);
           console.log(mySet)
            // 用...操作符,将 Set 转 Array
            var myArray = [...mySet];
            console.log(myArray)
    
    //var arr=Array.from(mySet)
    • String

    // String 转 Set
    var mySet = new Set('hello');  
    console.log(mySet);// Set(4) {"h", "e", "l", "o"}
    // 注:Set 中 toString 方法是不能将 Set 转换成 String

    Set==》转数组:使用静态函数  Array.from(mySet)

  • Set对象作用

    • 数组去重 (三种方法)

    //方法一:
    var mySet = new Set([1, 2, 3, 4, 4]);
    [...mySet]; // [1, 2, 3, 4]
    
    //方法二:
    var arr=[10,203,40,10]
    var s1=new Set(arr)
    var arr2=Array.from(s1)
    console.log(arr2)   //(3) [10, 203, 40]
    
    //方法三:
    根据对象中属性名不能重复   obj={age:20,age:30}==>obj={age:30}   //前面的会被覆盖
    就是创建一个对象,对象里的属性名是数组的元素:使用for遍历==》obj[arr[i]]=随便写一个数
    然后用Object.keys()   ==> 对象的所有属性名,返回一个数组
            //方法三:
            var arr = [2, 3, 4, 4, 6, 7, 8, 4, 9, 7]
            console.log(arr)
            var obj = {}
            for (var i = 0; i < arr.length; i++) {
                obj[arr[i]] = "11"
            }
            var re = Object.keys(obj)
            console.log(re)  
            var arr2=[]
            for(var j=0;j<re.length;j++) {
                arr2.push(parseInt(re[j]))
            }
            console.log(arr2)
    
    • 并集

    var a = new Set([1, 2, 3]);
    var b = new Set([4, 3, 2]);
    var union = new Set([...a, ...b]); // {1, 2, 3, 4}
    • 交集

    var a = new Set([1, 2, 3]);
    var b = new Set([4, 3, 2]);
    // var intersect = new Set([...a].filter(x => b.has(x))); // {2, 3}
    //上面一行代码等同于下面的代码
    var arr=[...a]
    var arr2=[...b]
    var arr3=arr.filter(function(el) {
        return arr2.has(el)   //就是看arr里面的每一个元素在不在arr2中,在就是true,filter会在返回值是true的时候,就把元素放进arr3中
     })
    • 差集

    var a = new Set([1, 2, 3]);
    var b = new Set([4, 3, 2]);
    var difference = new Set([...a].filter(x => !b.has(x))); // {1}

    ...

2、字符串

(1)子串的识别

ES6 之前判断字符串是否包含子串,用 indexOf 方法,ES6 新增了子串的识别方法

  • includes():返回布尔值,判断是否找到参数字符串。

  • startsWith():返回布尔值,判断参数字符串是否在原字符串的头部。

  • endsWith():返回布尔值,判断参数字符串是否在原字符串的尾部。

以上三个方法都可以接受两个参数,需要搜索的字符串,和可选的搜索起始位置索引

let string = "apple,banana,orange";
string.includes("banana");     // true
string.startsWith("apple");    // true
string.endsWith("apple");      // false
string.startsWith("banana",6)  // true

注意:

  • 这三个方法只返回布尔值,如果需要知道子串的位置,还是得用 indexOf 和 lastIndexOf 。

  • 这三个方法如果传入了正则表达式而不是字符串,会抛出错误。而 indexOf 和 lastIndexOf 这两个方法,它们会将正则表达式转换为字符串并搜索它。

(2)字符串重复

repeat():返回新的字符串,表示将字符串重复指定次数返回。

console.log("Hello,".repeat(2));  // "Hello,Hello,"

如果参数是小数,向下取整

console.log("Hello,".repeat(3.2));  // "Hello,Hello,Hello,"

如果参数是 0 至 -1 之间的小数,会进行取整运算,0 至 -1 之间的小数取整得到 -0 ,等同于 repeat 零次

console.log("Hello,".repeat(-0.5));  // "" 

如果参数是 NaN,等同于 repeat 零次

console.log("Hello,".repeat(NaN));  // "" 

如果参数是负数或者 Infinity ,会报错:

console.log("Hello,".repeat(-1));  
// RangeError: Invalid count value
​
console.log("Hello,".repeat(Infinity));  
// RangeError: Invalid count value

如果传入的参数是字符串,则会先将字符串转化为数字

console.log("Hello,".repeat("hh")); // ""
console.log("Hello,".repeat("2"));  // "Hello,Hello,"

(3)字符串补全

  • padStart:返回新的字符串,表示用参数字符串从头部补全原字符串。

  • padEnd:返回新的字符串,表示用参数字符串从尾部补全原字符串。

以上两个方法接受两个参数,第一个参数是指定生成的字符串的最小长度,第二个参数是用来补全的字符串。如果没有指定第二个参数,默认用空格填充。

console.log("h".padStart(5,"o"));  // "ooooh"
console.log("h".padEnd(5,"o"));    // "hoooo"
console.log("h".padStart(5));      // "    h"

如果指定的长度小于或等于原字符串的长度,则返回原字符串:

console.log("hello".padStart(5,"A"));  // "hello"

如果原字符串加上补全字符串长度大于指定长度,则截去超出位数的补全字符串:

console.log("hello".padEnd(10,",world!"));  // "hello,worl"

常用于补全位数:

console.log("123".padStart(10,"0"));  // "0000000123"

(4)模板字符串

模板字符串相当于加强版的字符串,用反引号 `,

除了作为普通字符串,还可以用来定义多行字符串,还可以在字符串中加入变量和表达式

注意:模板字符串中的换行和空格都是会被保留的。

        //普通字符串
        let string = `Hello'\n'world`;
        console.log(string); 
        //Hello'
        //'world
        
        //多行字符串
        let string1 = `Hey,
        can you stop angry now?`;
        console.log(string1);
        //Hey,
        //can you stop angry now?
        
        //变量名写在 ${} 中,${} 中可以放入 JavaScript 表达式。
        let name = "Mike";
        let age = 27;
        let info = `My Name is ${name},I am ${age+1} years old next year.`
        console.log(info);  //My Name is Mike,I am 28 years old next year.
    
        //字符串中调用函数
        function f(){
        return "have fun!";
        }
        let string2= `Game start,${f()}`;
        console.log(string2); // Game start,have fun!
        
        

(5)标签模板

标签模板,是一个函数的调用,其中调用的参数是模板字符串。

alert`Hello world!`;
// 等价于
alert('Hello world!');

应用:过滤 HTML 字符串,防止用户输入恶意内容。

function f(stringArr,...values){
    let result = "";
    for (let i = 0; i < stringArr.length; i++) {
        values[i] = stringArr[i];
        if (values[i]) {
        result += String(values[i]).replace(/&/g, "&amp;")
                        .replace(/</g, "&lt;")
                        .replace(/>/g, "&gt;");
        }
     }
     return result;
}
var name = f('<Amy&MIke>');
element.innerHTML = `<p>Hi, ${name}.I would like send you some message.</p>`;

3、数值

(1)数值的表示

  • 二进制表示法新写法: 前缀 0b 或 0B 。

console.log(0b11 === 3); // true
console.log(0B11 === 3); // true
  • 八进制表示法新写法: 前缀 0o 或 0O 。

console.log(0o11 === 9); // true
console.log(0O11 === 9); // true

(2)方法

  • Number.isFinite():用于检查一个数值是否为有限的( finite ),即不是 Infinity

console.log( Number.isFinite(1));   // true
console.log( Number.isFinite(0.1)); // true
 
// NaN 不是有限的
console.log( Number.isFinite(NaN)); // false
 
console.log( Number.isFinite(Infinity));  // false
console.log( Number.isFinite(-Infinity)); // false
 
// Number.isFinate 没有隐式的 Number() 类型转换,所有非数值都返回 false
console.log( Number.isFinite('foo')); // false
console.log( Number.isFinite('15'));  // false
console.log( Number.isFinite(true));  // false
Number.isNaN()
用于检查一个值是否为 NaN 。
console.log(Number.isNaN(NaN));      // true
console.log(Number.isNaN('true'/0)); // true
 
// 在全局的 isNaN() 中,以下皆返回 true,因为在判断前会将非数值向数值转换
// 而 Number.isNaN() 不存在隐式的 Number() 类型转换,非 NaN 全部返回 false
Number.isNaN("NaN");      // false
Number.isNaN(undefined);  // false
Number.isNaN({});         // false
Number.isNaN("true");     // false

  • Number.parseInt()从全局移植到 Number 对象的方法,逐步减少全局方法,用于全局变量的模块化。方法的行为没有发生改变。

// 不指定进制时默认为 10 进制
Number.parseInt('12.34'); // 12
Number.parseInt(12.34);   // 12
 
// 指定进制
Number.parseInt('0011',2); // 3
 
// 与全局的 parseInt() 函数是同一个函数
Number.parseInt === parseInt; // true
Number.parseFloat()
用于把一个字符串解析成浮点数。
Number.parseFloat('123.45')    // 123.45
Number.parseFloat('123.45abc') // 123.45
 
// 无法被解析成浮点数,则返回 NaN
Number.parseFloat('abc') // NaN
 
// 与全局的 parseFloat() 方法是同一个方法
Number.parseFloat === parseFloat // true
Number.isInteger()
用于判断给定的参数是否为整数。
Number.isInteger(value)
Number.isInteger(0); // true
// JavaScript 内部,整数和浮点数采用的是同样的储存方法,因此 1 与 1.0 被视为相同的值
Number.isInteger(1);   // true
Number.isInteger(1.0); // true
 
Number.isInteger(1.1);     // false
Number.isInteger(Math.PI); // false
 
// NaN 和正负 Infinity 不是整数
Number.isInteger(NaN);       // false
Number.isInteger(Infinity);  // false
Number.isInteger(-Infinity); // false
 
Number.isInteger("10");  // false
Number.isInteger(true);  // false
Number.isInteger(false); // false
Number.isInteger([1]);   // false
 
// 数值的精度超过 53 个二进制位时,由于第 54 位及后面的位被丢弃,会产生误判
Number.isInteger(1.0000000000000001) // true
 
// 一个数值的绝对值小于 Number.MIN_VALUE(5E-324),即小于 JavaScript 能够分辨
// 的最小值,会被自动转为 0,也会产生误判
Number.isInteger(5E-324); // false
Number.isInteger(5E-325); // true
Number.isSafeInteger()
用于判断数值是否在安全范围内。
Number.isSafeInteger(Number.MIN_SAFE_INTEGER - 1); // false
Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1); // false

(3)Math对象的扩展

ES6 在 Math 对象上新增了 17 个数学相关的静态方法,这些方法只能在 Math 中调用。

  • Math.cbrt():用于计算一个数的立方根。

Math.cbrt(1);  // 1
Math.cbrt(0);  // 0
Math.cbrt(-1); // -1
// 会对非数值进行转换
Math.cbrt('1'); // 1
 
// 非数值且无法转换为数值时返回 NaN
Math.cbrt('hhh'); // NaN
  • Math.imul():两个数以 32 位带符号整数形式相乘的结果,返回的也是一个 32 位的带符号整数。

// 大多数情况下,结果与 a * b 相同 
Math.imul(1, 2);   // 2
  • Math.hypot():用于计算所有参数的平方和的平方根。勾股定理

Math.hypot(3, 4); // 5

4、对象

(1)对象字面量

  • 属性的简洁表示法:ES6允许对象的属性直接写变量,这时候属性名是变量名属性值是变量值。

const age = 12;
const name = "Amy";
const person = {age, name};
console.log(person); //{age: 12, name: "Amy"}
  • 方法也可以简写:

const person = {
  sayHi(){
    console.log("Hi");
  }
}
person.sayHi();  //"Hi"
  • 属性名表达式:ES6允许用表达式作为属性名,但是一定要将表达式放在方括号内。

const obj = {
 ["he"+"llo"](){
   return "Hi";
  }
}
obj.hello();  //"Hi"

注意点:属性的简洁表示法 和 属性名表达式 不能同时使用,否则会报错。

const hello = "Hello";
const obj = {
 [hello]
};
console.log(obj);  //SyntaxError: Unexpected token }
 
const hello = "Hello";
const obj = {
 [hello+"2"]:"world"
};
console.log(obj); //{Hello2: "world"}

(2)对象的扩展运算符

拓展运算符(...)用于取出参数对象所有可遍历属性然后拷贝到当前对象。   

(... 可以取出数组、对象、集合、Map、形参中的所有元素)

  • 1、基本用法  (不是深拷贝,是浅拷贝,当对象中有引用数据的时候,是同一个空间)

let person = {name: "Amy", age: 15,arr:[1,2]};
let someone = { ...person };
console.log(someone,person.arr===someone.arr);  //{name: 'Amy', age: 15, arr: Array(2)} true

  • 2、可用于合并两个对象。同样适用于数组

let age = {age: 15};
let name = {name: "Amy"};
let person = {...age, ...name,n:100};
console.log(person);  //{age: 15, name: "Amy",n:100}  //属性名相同会覆盖
//对象的合并还可以用for循环来遍历,取key和value...

        var arr=[1,2,3]
        var arr2=[...arr]
        var arr3=[...arr,...arr2]
        console.log(arr3)  //(6) [1, 2, 3, 1, 2, 3]
//数组合并还可以用concat来合并==>   arr.concat(arr1)
  • 3、多个参数
        //多个参数用arg来代表
        // Function.prototype.mycall=function(self,...arg) {  //self代表的是第一个参数,arg代表的是剩余的参数
        //     this()
        // }
        // obj.say.mycall(1,2,3)
        // obj2.tool.mycall(2)
        
        function fn(...arg) {
            console.log(arg)
        }
        fn(1,2,3)  //(3) [1, 2, 3]

注意:自定义的属性和拓展运算符对象里面属性的相同的时候

  1. 自定义的属性在拓展运算符后面,则拓展运算符对象内部同名的属性将被覆盖掉。
let person = {name: "Amy", age: 15};
let someone = { ...person, name: "Mike", age: 17};
console.log(someone);  //{name: "Mike", age: 17}

2.自定义的属性在拓展运算度前面,则变成设置新对象默认属性值。

let person = {name: "Amy", age: 15};
let someone = {name: "Mike", age: 17, ...person};
console.log(someone);  //{name: "Amy", age: 15}

3.拓展运算符后面是空对象,没有任何效果也不会报错。

let a = {...{}, a: 1, b: 2};
console.log(a);  //{a: 1, b: 2}

4.拓展运算符后面是null或者undefined,没有效果也不会报错。

let b = {...null, ...undefined, a: 1, b: 2};
console.log(b);  //{a: 1, b: 2}

(3)对象的新方法

Object.is(value1, value2):用来比较两个值是否严格相等,与(===)基本类似。

Object.is("q","q");      // true
Object.is(1,1);          // true
Object.is([1],[1]);      // false
Object.is({q:1},{q:1});  // false

与===的区别

//一是+0不等于-0
Object.is(+0,-0);  //false
+0 === -0  //true
​
//二是NaN等于本身
Object.is(NaN,NaN); //true
NaN === NaN  //false

5、数组

工厂函数:不用new,就返回一个对象

(1)数组创建   

  • Array.of()

  • 将参数中所有值作为元素形成数组。

console.log(Array.of(1, 2, 3, 4)); // [1, 2, 3, 4]
console.log(Array.of(4));  //[4]    不是length,而是数组里的值

 
// 参数值可为不同类型
console.log(Array.of(1, '2', true)); // [1, '2', true]
 
// 参数为空时返回空数组
console.log(Array.of()); // []

  • Array.from()

  • 将类数组对象或可迭代对象转化为数组。

    // 参数为数组,返回与原数组一样的数组
    console.log(Array.from([1, 2])); // [1, 2]
     
    // 参数含空位
    console.log(Array.from([1, , 3])); // [1, undefined, 3]

    参数说明 (这些参数一般不用,可了解):Array.from(arrayLike[, mapFn[, thisArg]])

    • arrayLike:想要转换的类数组对象或可迭代对象。

    console.log(Array.from([1, 2, 3])); // [1, 2, 3]
    • mapFn:可选,map 函数,用于对每个元素进行处理,放入数组的是处理后的元素。

    console.log(Array.from([1, 2, 3], (n) => n * 2)); // [2, 4, 6]
    • thisArg:可选,用于指定 map 函数执行时的 this 对象。

    let map = {
        do: function(n) {
            return n * 2;
        }
    }
    let arrayLike = [1, 2, 3];
    console.log(Array.from(arrayLike, function (n){
        return this.do(n);
    }, map)); // [2, 4, 6]

  • 类数组对象

  • 一个类数组对象必须含有 length 属性,且元素属性名必须是数值或者可转换为数值的字符。

let arr = Array.from({
  0: '1',
  1: '2',
  2: 3,
  length: 3
});
console.log(); // ['1', '2', 3]
 
// 没有 length 属性,则返回空数组
let array = Array.from({
  0: '1',
  1: '2',
  2: 3,
});
console.log(array); // []
// 元素属性名不为数值且无法转换为数值,返回长度为 length 元素值为 undefined 的数组 
let array1 = Array.from({
  a: 1,
  b: 2,
  length: 2
});
console.log(array1); // [undefined, undefined]

  • 转换可迭代对象

    • 转换map

    let map = new Map();
    map.set('key0', 'value0');
    map.set('key1', 'value1');
    console.log(Array.from(map)); // [['key0', 'value0'],['key1','value1']]
    • 转换set

    let arr = [1, 2, 3];
    let set = new Set(arr);
    console.log(Array.from(set)); // [1, 2, 3]
    • 转换字符串    (字符串取里面的子串,一般用charAt)

    let str = 'abc';
    console.log(Array.from(str)); // ["a", "b", "c"]

(2)扩展的方法

  • 查找:

    • find():查找数组中符合条件的元素,若有多个符合条件的元素,则返回第一个元素。

    let arr = Array.of(1, 2, 3, 4);
    console.log(arr.find(item => item > 2)); // 3
     
    // 数组空位处理为 undefined
    console.log([, 1].find(n => true)); // undefined
    • findIndex():查找数组中符合条件的元素索引,若有多个符合条件的元素,则返回第一个元素索引。

    let arr = Array.of(1, 2, 1, 3);
    // 参数1:回调函数
    // 参数2(可选):指定回调函数中的 this 值
    console.log(arr.findIndex(item => item = 1)); // 0
     
    // 数组空位处理为 undefined
    console.log([, 1].findIndex(n => true)); //0
  • 填充:

    • fill():将一定范围索引的数组元素内容填充为单个指定的值。

    let arr = Array.of(1, 2, 3, 4);
    // 参数1:用来填充的值
    // 参数2:被填充的起始索引
    // 参数3(可选):被填充的结束索引,默认为数组末尾
    console.log(arr.fill(0,1,2)); // [1, 0, 3, 4]
  • 遍历:

    • entrys():遍历键值对。   一般不用这个,一般用Object.keys()

    for(let [key, value] of ['a', 'b'].entries()){
        console.log(key, value);
    }
    // 0 "a"
    // 1 "b"
     
    // 不使用 for... of 循环
    let entries = ['a', 'b'].entries();
    console.log(entries.next().value); // [0, "a"]
    console.log(entries.next().value); // [1, "b"]
     
    // 数组含空位
    console.log([...[,'a'].entries()]); // [[0, undefined], [1, "a"]]
    • keys():遍历键名。

    for(let key of ['a', 'b'].keys()){
        console.log(key);
    }
    // 0
    // 1
     
    // 数组含空位
    console.log([...[,'a'].keys()]); // [0, 1]
    • values():遍历键值

    for(let value of ['a', 'b'].values()){
        console.log(value);
    }
    // "a"
    // "b"
     
    // 数组含空位
    console.log([...[,'a'].values()]); // [undefined, "a"]
  • 包含:

    • includes():数组是否包含指定值。注意:与 Set 和 Map 的 has 方法区分;Set 的 has 方法用于查找值;Map 的 has 方法用于查找键名。 

    // 参数1:包含的指定值
    [1, 2, 3].includes(1);    // true
     
    // 参数2:可选,搜索的起始索引,默认为0
    [1, 2, 3].includes(1, 2); // false
     
    // NaN 的包含判断
    [1, NaN, 3].includes(NaN); // true
  • 嵌套数组转一维数组:

    • flat()   

    console.log([1 ,[2, 3]].flat()); // [1, 2, 3]
     
    // 指定转换的嵌套层数
    console.log([1, [2, [3, [4, 5]]]].flat(2)); // [1, 2, 3, [4, 5]]
     
    // 不管潜逃多少层
    console.log([1, [2, [3, [4, 5]]]].flat(Infinity)); // [1, 2, 3, 4, 5]
     
    // 自动跳过空位
    console.log([1, [2, , 3]].flat());<p> // [1, 2, 3]

 自己设置flat自调用函数 , 实现将数组的元素取出

	var arr=[[10,20,30],40,50,[[60,70],80,[90,[110],100]]]
			Array.prototype.myflat=function(count=Infinity){
				var arr=[]
				for(var i=0;i<this.length;i++){
					// arr.push(this[i])
					if(this[i].constructor==Array&&count>0){
						// for(var j=0;j<this[i].length;j++){
						// 	arr.push(this[i][j])
						// }
						var newarr=this[i].myflat(count-1)
						for(var j=0;j<newarr.length;j++){
							arr.push(newarr[j])
						}												
					}else{
						arr.push(this[i])
					}				
				}
				return arr
			}
			var re2=arr.myflat(1)
			console.log(re2)

(3)扩展运算符(...)

  • 复制数组:

        let arr = [1, 2],
            arr1 = [...arr];
        console.log(arr1,arr===arr1); // [1, 2]  false

        // 数组含空位
        let arr2 = [1, , 3],
            arr3 = [...arr2];
        console.log(arr3,arr2===arr3);   //[1, undefined, 3]   false
  • 合并数组:  (数组相同的不会覆盖)

        console.log([...[1, 2, 3],...[3, 4]]); //(5) [1, 2, 3, 3, 4]

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值