push等方法继承于Array这个构造函数.prototype属性上的方法

(1) 数组

1. 声明数组 (三种方式)

三种方式构造出来的数组都继承于 Array.prototype 的方法和属性

Array继承自Array.prototype,它下所有方法Array都可以用,也继承于Object.prototype
数组构造函数Array的原型prototype下的方法,如push等,像这些公共的方法肯定写原型prototype里,省内存空间
image.png
image.png

数组也可以看作一个对象,底层机制是一样的,数组可以看作是一种特殊的对象,如下
image.png
都是3
image.png

obj.name的机制
image.png

  1. var arr1 = [] //数组字面量声明
  2. var arr2 = new Array();// 通过系统内置的Array构造函数声明数组 不推荐使用
  3. var arr3 = Array();// 这种不使用
  4. // 相较于对象
  5. var obj1 = {};// 对象字面量声明
  6. var obj2 = new Object();// 通过系统内置的Object构造函数声明对象
  7. var obj3 = Object();
  8. arr = [1, 2, 3, 4, 5];
  9. // index 数组元素的下标(索引值) 从 0 开始
  10. // js 中数组是对象的一种形式
  11. /* js中数组的访问机制和对象一样*/
  12. var obj = {
  13. 0: 1,
  14. 1: 2,
  15. 2: 3,
  16. 3: 4,
  17. 4: 5,
  18. }
  19. //obj1.name->obj1['name']
  20. var arr = [, , ,]//最后一个是空值,会自动截掉最后一个逗号
  21. var arr = [, 2, , 4];// 稀松数组
  22. var arr1 = new Array(, 2, 1,,, 3, 1,);//用内置的构造函数构造的时候不能有空值,使用构造函数传的是参数
  23. var arr1 = new Array(5); // [, , , , ,] 3只填一个数字的时候就是创建数组的长度

2. 数组的操作

读取

  1. var arr = [1,2,3,4,5,6];
  2. console.log(arr[6]);
  3. console.log(arr[5]);

写入

  1. var arr = [1, 2, 3, 4, 5, 6];
  2. arr[6] = 'a';
  3. console.log(arr);//[1, 2, 3, 4, 5, 6, "a"]

修改

  1. var arr = [1, 2, 3, 4, 5, 6];
  2. arr[5] = 'a';
  3. console.log(arr)// [1, 2, 3, 4, 5, "a"]

3.数组方法

这些方法是修改原数组
push unshift 添加
pop shift 删除
reverse
splice
sort

添加

arr.push(参数) 在数组最后添加

  • 在数组的最后一位加,可以加多个值
  • 返回值:经过处理以后的数组长度
  • **push()** 方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度。
  • 参数 :要添加的数据,一个或多个号
  • 返回值:新的数组的长度 ```javascript var arr = [2, 3, 4]; arr.push(5)// 在数组的最后一位加,可以加多个值 arr.push(5, 6, 7) //返回值是处理之后数组的长度 7 console.log(arr); //[2, 3, 4, 5, 5, 6, 7] console.log(arr.push(1))//8 返回添加之后的length
  1. <a name="O0BYc"></a>
  2. #### push原理
  3. ```javascript
  4. //重写push方法
  5. var arr = [2,3,4];
  6. Array.prototype.myPush = function(){
  7. for(var i=0;i<arguments.length;i++){
  8. // arr[arr.length]=arguments[i];
  9. this[this.length] = arguments[i];
  10. }
  11. return this.length;
  12. }

arr.unshift(参数) 在数组的第一位添加

  • 在数组的第一位加,可以加多个值
  • 返回值:经过处理以后的数组长度
  • **unshift()** 方法将一个或多个元素添加到数组的开头,并返回该数组的新长度(该方法修改原有数组)

    1. var arr = [2, 3, 4];
    2. arr.unshift(5);// 在数组的第一位加,可以加多个值
    3. arr.unshift(6,7,8);//返回值是处理之后数组的长度 7
    4. console.log(arr); //[6, 7, 8, 5, 2, 3, 4]

    删除

    arr.pop() 删除数组最后一位

  • 剪切掉最后一位的值,没有参数

  • 返回值:返回被删除的值
  • **pop()**方法从数组中删除最后一个元素,并返回该元素的值。此方法更改数组的长度。

    1. var arr = [2, 3, 4];
    2. arr.pop() //返回值是4 [2,3]
    3. console.log(arr); //[2,3]

    image.png

    知道删除的是什么数据,当从后端接收返回的数据时很重要,返回值都是根据实际生产的需求而定

    arr.shift() 删除数组第一位

  • 剪切掉当前数组的第一位的值,没有参数

  • 返回值:返回被删除的值
  • **shift()** 方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。
  • https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/shift

    1. var arr = [2, 3, 4];
    2. arr.shift() //返回值是2 [3,4]
    3. console.log(arr); //[3,4]

    倒序

    arr.reverse()

  • **reverse()** 方法将数组中元素的位置颠倒,并返回该数组。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。该方法会改变原数组。

image.png
cba

剪切

  • arr.splice(开始项的下标,剪切的长度,剪切以后最后一位开始添加的数据)
  • **splice()** 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。
  • arr.splice(开始项的下标,剪切长度,剪切以后最后一位开始添加数据)
  • 返回值:被剪切的数据,可以是值也可以是数组

image.png

  1. var arr=['a','b','c']
  2. console.log( arr.splice(1,1))//b
  3. console.log(arr)//a,c

结果a,c 下标为1开始剪切,剪切一位

  1. var arr=['a','b','c']
  2. console.log( arr.splice(1,1,1,2,3))//b
  3. console.log(arr)//(5) ['a', 1, 2, 3, 'c']

image.png
结果abcde 在e的前面添加,在剪切元素前面添加数据,如果剪切的长度为0,返回空数组
image.png
-1是最后一位倒一,-2倒二,-3倒三

  1. // 开始项的下标 0代表第一位 -1代表倒数第一位
  2. var arr = [1,2,3,4,5,6,7];
  3. arr.splice(3,2); // arr[1,2,3,6,7]
  4. arr.splice(3,0,'a','b'); // arr[1,2,3,'a','b',6,7];
  5. arr.splice(-1,0,'c'); // arr[1,2,3,'a','b',6,'c',7];

splice() 原理

处理-1变成最后一位
image.png

  1. //重写splice方法
  2. function splice(arr,index){
  3. return index+=index>=0?0:arr.length-1;
  4. }

4.数组排序sort()

  • sort() 返回值: 返回排序之后的结果
  • sort 是按 ascii 码进行排列的,默认按照ascii码排列
  • 如果想要自定义排序方式sort(function(a,b))
  • 1.参数a,b

    1. 2.返回值:<br /> 负值 a就排在前面<br /> 正值 b就排在前面<br /> 0 保持不动

冒泡排序法,sort中就像for循环数组一样依次对比

image.png

  1. var arr2 = [27, 49, 5, 7];
  2. arr2.sort(function(a,b){
  3. return 1;
  4. })
  5. //arr2-> [27, 49, 5, 7] 不变
  6. arr2.sort(function(a,b){
  7. return -1;
  8. })
  9. //arr2->(4) [7, 5, 49, 27] 倒序
  10. console.log(arr2);

返回1 正值 ab顺序不变,就和参数ab顺序一样
返回-1 负值 ab顺序倒个
a27 b49
a27image.png
27 与5比 27>5 返回true正数 ,期望从小到大,所以把5放前面变成5 、27,所以返回1是b在前,变化,如果返回-1是a在前,不变
如果是1就变化b在前,-1不变a在前,a本来就是在前的

如果b小把b放前面就是升序,如果b大把b放前面就是降序

  1. sort(function(a, b){
  2. })
  3. //1.参数a,b
  4. //2.返回值:
  5. //负值 a就排在前面
  6. //正值 b就排在前面
  7. //0 保持不动
  8. var arr = [-1, -5, 8, 0, 2];
  9. arr.sort(); //[-1, -5, 0, 2, 8]
  10. var arr2 = [27, 49, 5, 7];
  11. // arr2.sort();
  12. // console.log(arr2);//[27, 49, 5, 7]
  13. arr2.sort(function(a,b){
  14. if(a>b){
  15. return 1;
  16. }else{
  17. return -1;
  18. }
  19. // return a - b; // 升序排列
  20. // return b - a; // 降序排列
  21. })
  22. console.log(arr2);

随机排序

  1. var arr = [1, 2, 3, 4, 5, 6];
  2. // Math.randon() -> 0-1 ;开区间
  3. arr.sort(function (a, b) {
  4. var rand = Math.random();
  5. if (rand - 0.5 > 0) {
  6. return rand;
  7. } else {
  8. return -1;
  9. }
  10. return Math.random() - 0.5;
  11. })
  12. console.log(arr)

对一个对象中的属性进行排序

  1. var arr = [{ name: "小明", age: 12, score: 100 },
  2. { name: "小红", age: 13, score: 80 },
  3. { name: "小花", age: 11, score: 90 } ];
  4. arr.sort(function(a,b){
  5. return b.age - a.age;
  6. });
  7. console.log(arr);

引用:

  1. var arr = [
  2. {
  3. son:'Jenny',
  4. age:18
  5. },
  6. {
  7. son:'Jone',
  8. age:10
  9. },
  10. {
  11. son:'Jone2',
  12. age:11
  13. },
  14. {
  15. son:'Jone3',
  16. age:13
  17. },
  18. {
  19. son:'Jone4',
  20. age:9
  21. }
  22. ]
  23. function sortBy(field) {
  24. return function(a,b) {
  25. return a[field] - b[field];
  26. }
  27. }
  28. arr.sort(sortBy("age"));
  29. console.log(arr);

image.png

总结

都是修改原始数组,原始数组改变

作业:

1.重写数组的原型上的unshift方法

自身写法

  1. var arr = [2,3,4];
  2. Array.prototype.myUnshift = function(){
  3. val = arguments.length-1;
  4. for(var i = val;i>=0;i--){
  5. this.splice(0,0,arguments[i]);
  6. }
  7. return this.length;
  8. }
  9. arr.myUnshift(1,2,3);
  10. console.log(arr);

解题思路:
使用splice()方法从实参的最后一位开始每次将一个元素放进新数组的第一位 ,数组最后一位的下标为length-1 倒数第二位为 __length-1 —

老师写法

  1. var arr = ['a','b','c'];
  2. Array.prototype.myUnshift = function(){
  3. for(var i=0;i<arguments.length;i++){
  4. this.splice(i,0,arguments[i]); //在数组第i位插入实参第i的值 //splcie 返回新数组
  5. }
  6. return this.length //unshift 也是返回数组长度
  7. }
  8. arr.myUnshift('1','2','3');
  9. console.log(arr);

解题思路:
使用splice()方法从实参的最后一位开始每次将一个元素放进新数组的第一位 ,数组最后一位的下标为length-1 倒数第二位为 __length-1 —

写法二 concat()

  1. var arr = ['a','b','c'];
  2. Array.prototype.myUnshift = function(){
  3. var arrArr = Array.prototype.slice.call(arguments);
  4. var newArr = arrArr.concat(this);
  5. return newArr;
  6. }
  7. var newArr = arr.myUnshift('a','b',1);
  8. console.log(newArr);

解题思路: 使用concat方法
难点:类数组没有concat方法
解决方案: 用 Array.prototype.slice.call()将具有length属性的对象转成数组

2.请按照字节数排序下列数组[‘我爱你’,’OK’,’Hello’,’你说WHAT’,’可以’]

  1. arr.sort(function(a,b){
  2. return getBytes(a) - getBytes(b); //进行字节比较
  3. })
  4. function getBytes(str){
  5. var bytes = str.length; //假设全是英文字符
  6. for(var i=0;i<str.length;i++) //下标从0-到length-1 所以循环i<str.length
  7. {
  8. if(str.charCodeAt(i)>255){
  9. bytes++;
  10. }
  11. }
  12. return bytes;
  13. }

解题思路: 使用 charCodeAt方法 计算字节数 再用sort进行排序
计算字节数
1.计算字节数假设字符串全是英文即字符串长度等于所占字节数: var bytes = str.length;
2.再进行循环判断每个数组元素字符串的具体字节数 i=0;i<str.length if(str.charCodeAt(i)>255)
若是中文字符 字节数 比英文字节数位数多1 则 bytes++ 假若__中文字符 字节数 比英文字节数位数多2
则bytes+=2;
3.返回每个数组元素字符串的具体字节数
sort排序
升序排列: return a - return b;
降序排列 __return b - return a;
arr.sort(function(a,b){
return getBytes(a) - __ getBytes(b)
})