类数组、数组去重
文章目录
类数组定义
类数组定义:长得像数组,也能当数组用,但就不是数组,数组有的方法它都没有。
function test() {
console.log(arguments);
arguments.push(7); // 报错 因为arguments不是数组
}
test( 1,3,3,4,5,6);
类数组的条件
1.属性要为索引(数字)属性
2.必须有length属性
3.最好加上push
类数组的特点
可以利用属性名模拟数组的特性
可以动态的增长length属性
如果强行让类数组调用push方法,则会根据length属性值的位置进行属性的扩充。
// 本身也是对象 但是用起来跟数组一样
var obj = {
"0" : 'a',
"1" : 'b',
"2" : 'c',
"length" : 3, // 类数组必须有length属性
"push" : Array.prototype.push // 最好加上push属性
}
obj.push('d') // push一个d之后会在类数组最后加这个属性 并且更改类数组长度
一旦给一个对象增加splice属性,这个对象就长得跟数组一样(变成[]),但是还是对象,可以当数组用。
var obj = {
"0" : 'a',
"1" : 'b',
"2" : 'c',
"length" : 3,
"push" : Array.prototype.push,
"splice" : Array.prototype.splice
}
数组和类数组
数组的调用方法
Array.prototype. push = function (target){
this[this.length] = target;
this.length ++;
}
对象(类数组)的调用方法
Array.prototype. push = function (target){
obj[obj.length] = target;
obj.length ++;
}
练习
练习一
// push 'c'和'd'之后的结果
var obj = {
"2" : "a" ,
"3" : "b",
"length" : 2,
"push" : Array.prototype.push
}
obj.push( 'c');
obj.push( 'd');
// 当前的length为2 push方法访问的是数组中数组长度的位置 所以会把原有的值给覆盖 而此时length++ 所以就是4 (看特点三)
// 注意看对象调用方法(length决定了把值push给谁 length的值就是push的属性)
Array.prototype. push = function (target){
obj[obj.length] = target;
obj.length ++;
}
var obj = {
"2" : ”c", // length是2 然后push的值是c
"3" : ”d", // length++之后是3 然后push的值是d
length : 4; // 然后length ++ 所以length最后是4 结果是2c 3d
}
练习二
var obj = {
"1" : 'a',
"2" : 'c',
"3" : 'd',
"length" : 3,
"push" : Array.prototype.push
}
obj.push( 'b'); // 结果是acb b替换length对应的3的属性值 length++之后是4
类数组的应用
既能像数组一样,又能像对象一样应用,但是不能用数组的方法,除非自己在对象中添加。
var obj = {
"0" : "a" ,
"1" : "b",
"2" : "c",
name : "abc" ,
age : 123,
length : 3,
push : Array.prototype.push,
splice : Array. prototype.splice
}
// 遍历类数组中的所有属性
for(var prop in obj) {
console.log(obj[prop])
}
作业
封装一个能精确判断数据类型的包装类(工具方法)
// 1.分两类_原始值引用值
// 2.区分引用值
function type(target) {
var ret = typeof(target);
var template = {
"[object Array]" : "array",
"[object 0bject]" : "object",
"[object Number]" : "number - object",
"[object Boolean]" : 'boolean - object',
"[object String]" : 'string - object'
}
if(target === null){
return null;
}else if(ret == "object") {
var str = Object.prototype.toString.call(target);
return ret;
}else {
return typeof(target);
}
}
数组去重
// 可以利用对象的特点(一个对象中属性名是唯一的,属性值可以重复)
var arr = [1,1,1,1,1,2,2,2,2,3,3,3,3,4]
// 把数组中的值依次作为属性名放到对象中
var obj = {
// 重复的就不管了 abc是随便赋值 最后直接把对象的属性名取出来就是去重后的数组
"1" : "abc",
"2" : "abc",
"3" : "abc",
"4" : "abc"
}
// 上述实现过程
// this指向数组是因为这是在Array的原型链上操作,谁调用this就指向谁
Array.prototype.unique = function () {
var temp = {}, // 这个对象是用来把数组的值当做属性名 来判断是否重复的
arr = [], // 定义一个数组放去重后的值
len = this.length;
// 不在循环中写i < this.length的好处时不用每次循环都计算一遍数组长度
for(var i = 0; i < len; i ++) {
if(!temp[this[i]]) { // 加! 表示temp这个对象中没有this[i]对应的值 也就是说明这个值没有重复
temp[this[i]] = "abc"; // 没重复的值作为temp对象的属性名并赋值abc 注意这里不能赋值为[this[i] 不然0不能去重 因为!0是true
arr.push(this[i]); // 没重复的值放入arr中
}
}
return arr;
}