初始化二维、一维数组 +es6新增的三个方法new Set、Array.from() 、new Map()+获取数组中最小值的四种方法+对象的四种遍历方法+sort()方法

js正确地使用fill()初始化二维数组:

fill()方法都知道,填充/改变 数组
比如:

let a = new Array(5).fill(0);
console.log(a); // 输出结果为[0, 0, 0, 0, 0]

当我们想使用fill创建一个二维数组时

let arr=new Array(5).fill(new Array(5).fill(0))
console.log(arr)

在这里插入图片描述
原因
fill()的参数不是基本类型时,比如数组、对象,并不是将它的值填充到数组,而是将它的地址填充到数组,所以填充后数组的每一项都指向的是同一个地址,就会出现"牵一发而动全身"的现象。

解决方法:使用map()给每个第一维的数组分别赋值

let arr4=new Array(5).fill(0).map(item=>new Array(5)) //二维的用不用fill填充都行,但是一维的必须填充,如果一维不填充,会导致比如 arr4[1][0]=8 就会报错,因为内存中压根就没开辟这个空间
//原因就是如果一维都不用fill填充,那么二维还怎么依赖他创建
let arr4=new Array(5).fill(0).map(item=>new Array(5).fill(0)) 


arr[1][1]=1
console.log(arr)  //这样就只有arr[1][1]发生改变了,完美解决。

创建一维数组的两种方式:
1、利用数组字面量

var arr = [1, 2, 3];
console.log(arr);    //输出结果为1,2,3

2、利用new Array()

var arr1 = new Array(); //创建了一个空的数组
console.log(arr1); //[]
var arr2 = new Array(2); //里面的2表示数组的长度为2,输出结果我2个空的数组元素
//虽然规定了长度,但要想任意再加长度之外的数组成员也是可以的 ,不受长度限制
console.log(arr2); // [empty × 2]  
var arr3 = new Array(2, 3); //等价于[2,3]   
 console.log(arr2); // [2, 3]

es6新增的三个api:
Set:set类似于数组,成员是唯一的
(1)成员不能重复
(2)只有键值没有键名,类似数组
(3)可以遍历,方法有add, delete,has
1.new Set()-----创建set对象
2.set.add(value)----存储值
3.set.get(value)---- set中不存在直接得到某个值的方法,若想取某个值必须用for of遍历,for或者forin都不行
4.set.has(value)----如果值存在则返回true,负责返回false
5.set.delete(value)----删除指定值
6.set.clear()----清空set
7.set.size----返回当前元素个数

Map:map类似于对象
(1)本质上是健值对的集合,类似集合
(2)可以遍历,可以跟各种数据格式转换
1.new Map()-----创建map对象
2.map.set(key,value)----根据键存储值
3.map.get(key)----根据键来返回值,如果map中不存在对应的key,则返回undefined
4.map.has(key)----如果key存在则返回true,负责返回false
5.map.delete(key)----删除指定键的值
6.map.clear()----清空map
7.map.size----返回当前元素个数

map和set构造函数具体可参考这篇文章
Set是es6新增的数据结构,类似于数组也类似对象,但它的一大特性就是所有元素都是唯一的,没有重复的值,我们一般称为集合。

Set是一个构造函数,用来生成 Set 数据结构(构造函数中有对数组特有的 添加元素add方法、删除元素 delete方法、判断某元素是否存在has方法、清除所有元素clear方法 )

Array.from() 方法可将拥有 length 属性的对象或可迭代的对象(迭代就是可根据上一次值推出下一次值,比如for循环语句)转化为一个数组并返回(es6新增)

new Set()和Array.from() 结合用来数组去重
new Set(),用来数组去重。
Set类似于数组,区别在于它所有的成员都是唯一的,不能有重复的值
Array.from()或者...扩展运算符可以将set数据结构变更为数组形式

数值去重:
let arr = [1, 2, 2, 3];  // [1, 2, 2, 3]
let set = new Set(arr);  //去掉重复数据,返回结果是'set'
let newArr = Array.from(set);  //将set转化为数组或者利用扩展运算符
let newArr2=[...set]  //通过...扩展运算符将set变更为数组形式
console.log(newArr2);  // [1, 2, 3]
console.log(newArr); // [1, 2, 3]

 

对象用变量表示去重:
const b={a:2}
let arr = [{a:1}, b, b, {a:3}];  //[{a:1},{a:2},{a:2},{a:3}]
let set = new Set(arr);
let newArr = Array.from(set);
console.log(newArr); // [{a:1},{a:2},{a:3}]


无法直接对象去重:
let arr = [{a:1}, {a:2}, {a:2}, {a:3}];  //[{a:1},{a:2},{a:2},{a:3}]
let set = new Set(arr);
let newArr = Array.from(set);
console.log(newArr); //[{a:1},{a:2},{a:2},{a:3}]
/// 将Set结构的数据转换为真正的数组  
let arr = [12,45,97,9797,564,134,45642]
let arr2 = new Set(arr)  //arr2是可迭代的对象,但没有 length 属性,有size属性
console.log(Array.from(arr2))  // [ 12, 45, 97, 9797, 564, 134, 45642 ]
 var myarr=Array.from("sdv")  //sdv是可迭代的对象
 console.log(myarr);  //['s', 'd', 'v']
	let arrayLike = {
	    0: 'tom', 
	    1: '65',
	    2: '男',
	    3: ['jane','john','Mary'],
	    'length': 4
	}
	let arr = Array.from(arrayLike)
	console.log(arr) // ['tom','65','男',['jane','john','Mary']]

let arrayLike = {
    'name': 'tom', 
    'age': '65',
    'sex': '男', 
    'friends': ['jane','john','Mary'],
    'length': 4
}
let arr = Array.from(arrayLike)    //arrayLike的键导致arrayLike是不可迭代的对象
console.log(arr)  // [ undefined, undefined, undefined, undefined ]

Javascript五种方法获取数组中最小值:

var arry = [1, 3, 2, 9, 5, 3, 1, 5, 3, 0, 9, 3, 2, 4, 2, 5, 7];
//方法一:循环遍历
var minNum = arry[0];
arry.forEach((val, index) => {
if (val < arry[index + 1] && val < minNum) {
minNum = val;
}
})
console.log(minNum)


//方法二:sort()
sort() 方法用于对数组的元素进行排序。排序顺序可以是字母或数字,并按升序或降序。
默认排序顺序为根据ASCLL码升序。当数字是按字母顺序排列时"40"将排在"5"前面(因为是根据ASCLL码进行排序)。
所以你必须通过一个函数作为参数来调用。函数指定数字是按照升序还是降序排列。

sort()可以接收一个携带两个形参的callback(a,b),即a、b是两个即将要比较大小的元素,且必须要有返回值。
当callback的返回值是正数时、那么 b 会被排列到 a 之前;
当callback的返回值是负数时、那么 a 会被排列到 b 之前;
当callback的返回值是为 0 时、那么 a 与 b 的位置保持不变;
sort每执行一次会根据返回值调换两个参数a、b在原数组中的位置
(a = > 当前项、b当前项的下一项)

 arry.sort((a,b) => {
     return a-b
 })
 console.log(arry[0])


//方法三:Math.min()+... 
Math.min(...arry)


//方法四:reduce()
let arry = [11, 12, 13, 14, 15, 16, 17, 12, 12, 9, 11];
let result = arry.reduce((x, y) => x < y ? x : y)
console.log(result)//9

//方法五:巧用apply方法,因为apply方法它在执行的时候,可以将传入的数组解析成一个一个的元素。
let arr = [23,1,33,6,8,2];
min = Math.min.apply(null,arr)
console.log(min)   //1

sort()方法的具体使用请点击此处

JS中对象的四种遍历方法:

  1. for in 遍历
    for in用来遍历对象自身和其可枚举属性(不含symbol属性),且可遍历对象原型上的属性。
let obj = {
  name: 'hong',
  age: 20,
  sex: 'nan'
}
 
Object.prototype.scholl = 'wyu'
Object.prototype.say = function () {
  console.log('hello!')
}
 
for (let i in obj) {
  console.log(i + ':' + obj[i])
}
 
// 打印以下信息
// name:hong
// age:20
// sex:nan
// scholl:wyu
// say:function () {
//   console.log('hello!')
// }

若只遍历对象上的实例属性,不遍历对象原型上的属性,可用 hasOwnProperty 来判断一下是否为该对象实例的属性,再进行遍历。

for (let i in obj) {
  if (obj.hasOwnProperty(i)) {
    console.log(i + ':' + obj[i])
  }
}
// 输出
name:hong
age:20
sex:nan
  1. 使用 Object.keys (返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性))和 Object.values 遍历
let obj = {
  name: 'hong',
  age: 20,
  sex: 'nan'
}
 
console.log(Object.keys(obj)) //[ 'name', 'age', 'sex' ]
console.log(Object.values(obj)) //[ 'hong', 20, 'nan' ]

Object.keys在内部会根据属性名key的类型进行不同的排序逻辑,分三种情况:
如果属性名的类型是Number,那么Object.keys返回值是按照key从小到大排序
如果属性名的类型是String,那么Object.keys返回值是按照属性被创建的时间升序排序。
如果属性名的类型是Symbol,那么逻辑同String相同

  1. Object.getOwnPropertyNames(obj) 方法
    返回一个数组,包含对象自身的所有属性(不含Symbol属性,但是包括不可枚举属性).
let obj = {
  name: 'hong',
  age: 20,
  sex: 'nan'
}
 
let objKeys = Object.getOwnPropertyNames(obj)
console.log(objKeys) //[ 'name', 'age', 'sex' ]

4.Reflect.ownKeys(obj)遍历
返回一个数组,包含对象自身的所有属性,不管属性名是Symbol或字符串,也不管是否可枚举

let obj = {
  name: 'hong',
  age: 20,
  sex: 'nan'
}
 
console.log(Reflect.ownKeys(obj)) //['name', 'age', 'sex']

Reflect是ES6提供的新对象,将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty,Proxy对象上所有新增函数等),放到Reflect对象上,从Reflect上能拿到js语言内部的方法。
Reflect也算是一个js内置对象,它提供拦截JavaScript操作的方法。Reflect不是一个函数对象,因此它是不可构造的。

说一个Reflect对象方法和object对象方法的不同:

Reflect.defineProperty()是一个静态的方法,看起来像Object.defineProperty()但是它返回一个布尔值
Object.defineProperty()也是静态方法,但返回更改后的对象
const object1 = {};
console.log(Reflect.defineProperty(object1, "property1", { value: 42 })); //true
console.log(Object.defineProperty(object1, "property2", { value: 30 }));  //{property1: 42, property2: 30}

console.log(object1); //{property1: 42, property2: 30}
 

静态方法对应实例(动态)方法:

静态方法
function A(){}
A.sayMeS=function(){
console.log("Hello World S!");
}
A.sayMeS();//输出Hello World S!
(动态)实例方法
function A(){
  this.sayMeE=function(){
console.log("Hello World E!");
}}
A.sayMeE() //A.sayMeE is not a function 报错
var a=new A(); //var a是A的一个引用,也就是指针,a就可以指向sayMeE这个方法
a.sayMeE();//输出Hello World E!

附(不知名知识点):

forin循环:只遍历对象自身的和继承的可枚举的属性。
Object.keys():返回对象自身的所有可枚举的属性的键名。
JSON.stringify():只串行化对象自身的可枚举的属性
Object.assign():只拷贝对象自身的可枚举的属性。

其中,只有forin会返回继承的属性,其他三个方法都会忽略继承的属性,只处理对象自身的属性
实际上,引入“可枚举”(enumerable)这个概念的最初目的,就是让某些属性可以规避掉forin操作,
不然所有内部属性和方法都会被遍历到。比如,对象原型的toString方法,以及数组的length属性,
就通过“可枚举性”,从而避免被forin遍历到。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值