js是一门很神奇(niubi)的语言,容易上手却不易精通,因为里面的弯弯绕绕太多了
以下是由js对象数组去重引出的一系列知识点总结:
先上代码
//待去重数组
let arr = [{name:"123",value:123},{name:"123",value:123},{name:"321",value:321},{name:"321",value:123},{name:"111",value:123},{name:"222",value:123}]
//去重方法
Array.prototype.unique1 = function(){
let emptyObj = {} //创建空对象,用于存放属性
let result = [] //结果数组,用于存放结果
for(let i = 0;i<this.length;i++){//this指向调用该方法的数组
this[i] = JSON.stringify(this[i])//将对象解析为字符串便于比较
if(!emptyObj[this[i]]){//以emptyObj是否存在该字符串为名的属性进行判断
emptyObj[this[i]] = 1 //将emptyObj的this[i]属性设为1,便于判断
result.push(JSON.parse(this[i]))//将字符串重新解析为对象
}
}
return result //返回结果
}
//打印结果
console.log(arr.unique1())
let arr = [{name:"123",value:123},{name:"123",value:123},{name:"321",value:321},{name:"321",value:123},{name:"111",value:123},{name:"222",value:123}]
//去重方法
Array.prototype.unique1 = function(){
let emptyObj = {} //创建空对象,用于存放属性
let result = [] //结果数组,用于存放结果
for(let i = 0;i<this.length;i++){//this指向调用该方法的数组
this[i] = JSON.stringify(this[i])//将对象解析为字符串便于比较
if(!emptyObj[this[i]]){//以emptyObj是否存在该字符串为名的属性进行判断
emptyObj[this[i]] = 1 //将emptyObj的this[i]属性设为1,便于判断
result.push(JSON.parse(this[i]))//将字符串重新解析为对象
}
}
return result //返回结果
}
//打印结果
console.log(arr.unique1())
输出结果为
思路
数组去重最核心的思路,就是将每个数组中的元素都进行比较,去除相同的结果
如何利用好js的特性,进行合理高效的操作是个不错的问题
在这里我采取了使用空对象存值,然后通过对象属性的唯一性来进行筛选判断的方法
对于稍微有些基础的人,看起来还是比较容易理解的
以下是对上述代码涉及到知识的总结:
let是es6新出的一个属性,用于定义变量。它有一个特别神奇的功能-----定义作用域,这是极为实用的功能,可以达到部分闭包的效果。在这里没有体现,暂时不表。
Array是js默认的数组对象,所有数组对象都是该对象的一个子集,是它的一个具体表现
var arr = [] 等价于 var arr = new Array()
在实际使用中,推荐使用 var arr = []
所有new出来的数组对象,都是相互独立的,但是它们都继承了同一个Array对象的属性和方法
这种继承涉及到一个js的知识点,原型属性(prototype)
每个对象都有它自己的原型属性,prototype实际上是对象类型的引用
通过原型属性,所有new出来的对象都可以继承到原型对象的属性和方法。
简而言之,所有new出来的对象,保持了同一个引用
js对象的定义方法大致可以分为两种:
基于js原有Object对象new出对象及增加属性和方法的方式
var obj = new Object()
obj.name = "张三"
obj.sayname = function(){
alert(this.name)
}
通过构造函数创建对象及增加属性和方法的方式
function obj(){
this.name = "张三"
this.sayname = function(){
alert(this.name)
}
}
通过以上两种方式为基础,可以引申出大量对象定义模式:如工厂方式,原型方式等
最为常用的是对象字面量法
var obj = {
name:"张三",
sayname:function(){
alert(this.name)
}
}
此外,对象获取属性的方法还有一种
obj["name"]等价于obj.name,此方法的优点是可以获取对象中的特殊字符格式属性
var obj = {
名字:"张三",
"a.b":"123"
}
很显然,如果我们obj.名字和obj.a.b肯定就报错了,而使用obj["名字"],obj["a.b"]则可以正常获取属性(在此默默鄙视一下曾经在返回json中用中文当key值的后台小伙伴)
对象有一个特点,当你在其中重复定义同名属性,它只会取最后一次定义的值,与定义变量是一样的
上诉去重就是通过该特点进行判断筛选的
JSON.stringify()和JSON.parse()算是很常用的两种方法
JSON.stringify()可以将json对象转换为字符串,上述去重就是将对象转换为字符串从而方便判断的
JSON.parse()则恰好与JSON.stringify()相反,它的作用是将json字符串解析为json对象
在日常开发中,这两个函数可以说是相当好用,多用于抠假数据,数据格式化等等
引申一下,JSON.parse(JSON.stringify(obj))可以实现对象深拷贝,但是无法拷贝函数