总结

这些方法都是新建数组,不改变原数组的方法

数组方法

concat

**concat()** 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
返回全部的集合,返回集合成的数组

  1. var arr1 = ['a','b','c'];
  2. console.log(arr1);
  3. var arr2 = ['d','e','f'];
  4. console.log(arr2);
  5. var arr3 = arr1.concat(arr2); //["a", "b", "c", "d", "e", "f"]
  6. var arr4 = arr2.concat(arr1); //["d", "e", "f", "a", "b", "c"]
  7. console.log(arr3);
  8. console.log(arr4);

toString

**toString()** 返回一个字符串,表示指定的数组及其元素。
数组转字符串有,逗号

  1. var arr5 = ['a','b','c','d'];
  2. var arr6 = [1,2,3,4,5,6,7];
  3. console.log(arr5.toString()); // a,b,c,d
  4. console.log(arr6.toString()); // 1,2,3,4,5,6,7

slice

**slice()** 方法返回一个新的数组对象,这一对象是一个由 beginend 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
参数开始下标(键名),结束下标,前闭后开[begin,end),不包括end,end之前
image.png
与arr的结果一样,但是存储不同的空间地址,相当于拷贝了一份,把新的空间地址赋值给arr1
image.png
[bcdef]
从下标1开始截取
image.png
截取到4之前,而不是之后
image.png
de -1之前由小到大

  1. // slice
  2. // [start,end) => (start,end)
  3. var arr7 = ['a','b','c','d','f'];
  4. var arr8 = arr7.slice(3); // ["c", "d"]
  5. console.log(arr8);

join

加入
**join()** 方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符。

  1. var arr = ['a','b','c','d'];
  2. var str1 = arr.join('-');
  3. console.log(str1); // a-b-c-d

split

分隔
**split() **方法使用指定的分隔符字符串将一个[String](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String)对象分割成子字符串数组,以一个指定的分割字串来决定每个拆分的位置。
参数:(以什么为间隔符,数字截取几位)

  1. var arr = ['a','b','c','d'];
  2. var str1 = arr.join('-');
  3. console.log(str1); // a-b-c-d
  4. var arr1 = str1.split('-');
  5. console.log(arr1); // ["a", "b", "c", "d"]

类数组

类数组定义
  1)拥有length属性,其它属性(索引)为非负整数(对象中的索引会被当做字符串来处理);
2)不具有数组所具有的方法;
类数组vs数组

探究

打印arguments 结果很像一个数组
image.png
image.png
看看能不能调用push方法,结果报错
image.png
image.png
image.png
image.png
如果加push,依然会报错

为什么没有push,因为不是真正的数组Array,不继承Array.prototype
一定有length属性

image.png
自己写的类数组,打印结果不是符号不是[],而是{}
image.png

image.png
加上splice继承splice
image.png
结果就变成了【】
类数组没有push也可以继承
因为所有对象都继承自object.prototype ,所以在它上面添加方法,新建方法并指向array的方法中

  1. Object.prototype.push = Array.prototype.push;//在Object原型中新建push方法,不是重写,Object原型中没有push方法
  2. function test() {
  3. var arr = [1,2,3,4,5,6,7];
  4. arguments.push(8); // 不继承=> Array.prototype
  5. console.log(arguments,arr);
  6. }
  7. test(1,2,3,4,5,6,7)

argument继承object,数组继承Array
image.png

  1. function test() {
  2. arguments.push(7); // 不继承=> Array.prototype
  3. console.log(arguments);
  4. }
  5. test(1,2,3,4,5,6,7)

image.png

如何解决

  1. Object.prototype.push = Array.prototype.push;
  2. function test() {
  3. arguments.push(8); // 不继承=> Array.prototype
  4. console.log(arguments);//Arguments(8) [1, 2, 3, 4, 5, 6, 7, 8, callee: ƒ, Symbol(Symbol.iterator): ƒ]
  5. }
  6. test(1,2,3,4,5,6,7)

执行push时length加1

push原理

使得push时length加1

  1. Array.prototype.push = function (elem) {
  2. this[this.length] = elem;
  3. this.length++;
  4. }
  1. Object.prototype.push = Array.prototype.push;
  2. function test() {
  3. arguments.push(8); // 不继承=> Array.prototype
  4. arguments.push(9)
  5. arguments.push(10)
  6. console.log(arguments);
  7. }
  8. Array.prototype.push = function (elem) {
  9. this[this.length] = elem;
  10. this.length++;
  11. }
  12. test(1, 2, 3, 4, 5, 6, 7);

Arguments(10) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, callee: ƒ, Symbol(Symbol.iterator): ƒ]
依然是length变成10

push面试题

  1. var obj ={
  2. '2':3,
  3. '3':4,
  4. 'length':2,
  5. 'splice':Array.prototype.splice,
  6. 'push':Array.prototype.push
  7. }
  8. obj.push(1);
  9. obj.push(2);
  10. console.log(obj);
  11. //obj[2] = 1;
  12. //obj[3] = 2;

参考push原理 push根据数组的length属性为索引确定数组位置添加数组元素
此时this.length 等于 2 elem = 1 => this.length 等于 3 elem = 2 => this.length 等于 4

属性是字符串,obj.name转换成obj[‘name’],name转换成字符串,obj.1错误,1不会转换成obj[‘1’]

因为length是2默认是2,从obj[2]开始,obj[1],obj[2]都是空的
obj[2]=1,length+1=3 ,obj [3]=2, length+1=4
image.png

image.png
既是类,又有数组的特性,length的长度跟随着012的个数,不看别的属性的个数,一定要有length属性
image.png

作业:

1.封装typeof

  1. function myTypeof(val){
  2. var type = typeof(val);
  3. var toStr = Object.prototype.toString;
  4. var res = {
  5. '[object Array]': 'array',
  6. '[object Object]': 'object',
  7. '[object Number]': 'object number',
  8. '[object String]': 'object string',
  9. '[object Boolean]': 'object boolean'
  10. }
  11. if(val === null){
  12. return null; //先判断是否是null类型因为 null 是特殊的object型 如果是的话就先排除
  13. }else if(type === 'object'){ //判断是否是引用类型的数据
  14. var ret = toStr.call(val); //判断具体的引用类型
  15. return res[ret]; //返回对象中具体的引用类型
  16. }else{
  17. return type; //若不是引用类型的数据 则直接返回type类型数据
  18. }
  19. }
  20. console.log(myTypeof(new Number(1)));

2.数组去重

  1. var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
  2. Array.prototype.unique = function(){
  3. var temp = {},
  4. newArr = [];
  5. for(var i = 0;i<this.length;i++){
  6. if(!temp.hasOwnProperty(this[i])){
  7. temp[this[i]] = this[i];
  8. newArr.push(this[i]);
  9. }
  10. }
  11. return newArr;
  12. }
  13. console.log(arr.unique())

解题思路: 利用键名唯一的特性__hasOwnProperty
设置一个空对象,遍历数组 判断传入的每个数组元素是否为其属性 如果不是则空对象传入此属性
新数组加入此元素.

字符串去重

  1. var str = '1122333aaaabbbbb';
  2. String.prototype.unique = function(){
  3. var temp = {},
  4. newArr = '';
  5. for(var i=0;i<this.length;i++){
  6. if(!temp.hasOwnProperty(this[i])){
  7. temp[this[i]] = this[i];
  8. newArr+=this[i];
  9. }
  10. }
  11. return newArr;
  12. }
  13. console.log(str.unique());