(10)内置对象-1

2019-05-05  本文已影响0人  汨逸

内置对象

我们平时忙于开发,很少有时间能够将文档看一遍。这样在很多时候,我们本可以一个原生方法能够实现的程序,却累的跟狗一样,写出来的程序还不定好使。为了减少重复造轮子的时间,将MDN的API结合自己的理解,归纳整理了下面的文档。MDN文档-JavaScript内置对象

1 Array对象

var arr = ['Tom','John','Amy'];
arr.length    // 3
var arr1 = ['a', 'b', 'c'];
var arr2 = ['d', 'e', 'f'];
var arr3 = arr1.concat(arr2);    // [ "a", "b", "c", "d", "e", "f" ]
var arr = ['Tom','John','Amy'];
arr.join('#');    // Tom#John#Amy
var arr = ['Tom','John','Amy'];
arr.push('Jack');    // 4
arr        // ['Tom','John','Amy','Jack']
var arr = ['Tom','John','Amy'];
arr.pop();    // Amy
arr        // ['Tom','John']
var arr = ['Tom','John','Amy'];
arr.shift();    // Tom
arr        // ['John','Amy']
var arr = ['Tom','John','Amy'];
arr.unshift('Jack');    // 4
arr        // ['Jack',Tom','John','Amy']
var arr = ['Tom','John','Amy'];
arr.sort();    // ["Amy", "John", "Tom"]
arr        // 改变原数组:["Amy", "John", "Tom"]
var arr = ["Amy", "John", "Tom"];
arr.reverse()    // ['Tom', 'John', 'Amy']
var arr = ["Amy", "John", "Tom"];
arr.indexOf('John');    // 1
arr.indexOf('David');    // -1
var arr = ["Amy", "John", "Tom", "David", "Tom", "Jeff"];
arr.lastIndexOf('Tom');    // 4
arr.lastIndexOf('James');    // -1
var arr = ["Amy", "John", "Tom", "David", "Jeff"];
arr.slice(2)    // ["Tom", "David", "Jeff"]
arr            // 原数组不发生变化,["Amy", "John", "Tom", "David", "Jeff"]

var arr = ["Amy", "John", "Tom", "David", "Jeff"];
arr.slice(2,4)    // 不包含结束位置 ["Tom", "David"]    
var arr = ["Amy", "John", "Tom", "David", "Jeff"];
arr.splice(2)    // ["Tom", "David", "Jeff"]
arr            // 原数组发生变化,["Amy", "John"]

var arr = ["Amy", "John", "Tom", "David", "Jeff"];
arr.splice(2,2)    // ["Tom", "David"]
arr            // 原数组发生变化,["Amy", "John", "Jeff"]
var arr = ["Amy", "John", "Tom"];

arr.forEach(function(element) {
  console.log(element);
});

// expected output: "Amy"
// expected output: "John"
// expected output: "Tom"

注意:
1. forEach 遍历的范围在第一次调用 callback 前就会确定
2. 调用 forEach 后添加到数组中的项不会被 callback 访问到
3. 如果已经存在的值被改变,则传递给 callback 的值是 forEach 遍历到他们那一刻的值。
4. 已删除的项不会被遍历到
5. 如果已访问的元素在迭代时被删除了(例如使用 shift()),之后的元素将被跳过
6. forEach() 为每个数组元素执行callback函数;不像 map() 或者 reduce(),它总是返回 undefined 值,并且不可链式调用
7. forEach() 被调用时,不会改变原数组(即调用它的数组),即使传递的参数里的 callback被调用时可能会改变原数组
8. 没有办法中止或者跳出 forEach() 循环,除了抛出一个异常
    需要终止:
    1. 简单for循环
    2. for...of循环
    3. arr.every()
    4. arr.some()
    5. arr.find()
    6. arr.findIndex()
    7. 先使用filter再forEach也可以
9. 如果使用箭头函数,第二个thisArg参数忽略  
var arr = [16,22,15,33,38,28];

// 要求:数组中的每个元素的值都必须大于18为true,其余都为假
arr.every(function(value){
    return value > 18;
})    // false
var arr = [16,22,15,33,38,28];

// 要求:数组中的每个元素都小于18为true,其余都为真
arr.some(function(value){
    return value > 18;
})        // true

var arr = [16,22,15,33,38,28];

// 要求:数组中的每个元素的值都必须大于18为true,其余都为假
arr.map(function(value){
    return value + 10;
})    // [26,32,25,43,48,38]
var arr = [16,22,15,33,38,28];

// 要求:数组中超过18的元素都被筛选出来
arr.filter(function(value){
    return value > 18;
})    // [22,33,38,28]
Array.isArray([1, 2, 3]);      // true
Array.isArray({foo: 123});    // false
Array.isArray("foobar");  // false
Array.isArray(undefined);  // false

与instanceof区别:
Array.isArray()能检测iframes,instanceof不能检测

// 案例
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3); // [1,2,3]

// Correctly checking for Array
Array.isArray(arr);  // true
// Considered harmful, because doesn't work though iframes
arr instanceof Array; // false
[0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array){
    return accumulator + currentValue;
});    // 最终结果:10

accumulator:计算值
currentValue: 当前值
currentIndex: 当前索引值
array: 处理的数组
callback 计算值 当前值 当前索引 处理的数组 返回值
第一次调用 0 1 1 [0, 1, 2, 3, 4] 1
第二次调用 1 2 2 [0, 1, 2, 3, 4] 3
第三次调用 3 3 3 [0, 1, 2, 3, 4] 6
第四次调用 6 4 4 [0, 1, 2, 3, 4] 10

可以完成的事情:

  1. 数组所有值求和(案例同上)

  2. 累加对象数组的值

    var initialValue = 0;
    var sum = [{x: 1}, {x:2}, {x:3}].reduce(
        (accumulator, currentValue) => accumulator + currentValue.x
        ,initialValue
    );
    
    console.log(sum) // logs 6
    
  1. 将二维数组转为一维数组

    var flattened = [[0, 1], [2, 3], [4, 5]].reduce(
      function(a, b) {
        return a.concat(b);
      },
      []
    );
    // flattened is [0, 1, 2, 3, 4, 5]
    
  2. 计算数组中每个元素出现的次数

    var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
    
    var countedNames = names.reduce(function (allNames, name) { 
      if (name in allNames) {
        allNames[name]++;
      }
      else {
        allNames[name] = 1;
      }
      return allNames;
    }, {});
    // countedNames is:
    // { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }
    
  3. 按属性对object分类

    var people = [
      { name: 'Alice', age: 21 },
      { name: 'Max', age: 20 },
      { name: 'Jane', age: 20 }
    ];
    
    function groupBy(objectArray, property) {
      return objectArray.reduce(function (acc, obj) {
        var key = obj[property];
        if (!acc[key]) {
          acc[key] = [];
        }
        acc[key].push(obj);
        return acc;
      }, {});
    }
    
    var groupedPeople = groupBy(people, 'age');
    // groupedPeople is:
    // { 
    //   20: [
    //     { name: 'Max', age: 20 }, 
    //     { name: 'Jane', age: 20 }
    //   ], 
    //   21: [{ name: 'Alice', age: 21 }] 
    // }
    
  4. 使用扩展运算符和initialValue绑定包含在对象数组中的数组

  5. // friends - 对象数组
    // where object field "books" - list of favorite books 
    var friends = [{
      name: 'Anna',
      books: ['Bible', 'Harry Potter'],
      age: 21
    }, {
      name: 'Bob',
      books: ['War and peace', 'Romeo and Juliet'],
      age: 26
    }, {
      name: 'Alice',
      books: ['The Lord of the Rings', 'The Shining'],
      age: 18
    }];
    
    // allbooks - list which will contain all friends' books +  
    // additional list contained in initialValue
    var allbooks = friends.reduce(function(prev, curr) {
      return [...prev, ...curr.books];
    }, ['Alphabet']);
    
    // allbooks = [
    //   'Alphabet', 'Bible', 'Harry Potter', 'War and peace', 
    //   'Romeo and Juliet', 'The Lord of the Rings',
    //   'The Shining'
    // ]
    
  6. 数组去重

    let arr = [1,2,1,2,3,5,4,5,3,4,4,4,4];
    let result = arr.sort().reduce((init, current) => {
        if(init.length === 0 || init[init.length-1] !== current) {
            init.push(current);
        }
        return init;
    }, []);
    console.log(result); //[1,2,3,4,5]
    
  7. 按顺序运行promise

    /**
     * Runs promises from array of functions that can return promises
     * in chained manner
     *
     * @param {array} arr - promise arr
     * @return {Object} promise object
     */
    function runPromiseInSequence(arr, input) {
      return arr.reduce(
        (promiseChain, currentFunction) => promiseChain.then(currentFunction),
        Promise.resolve(input)
      );
    }
    
    // promise function 1
    function p1(a) {
      return new Promise((resolve, reject) => {
        resolve(a * 5);
      });
    }
    
    // promise function 2
    function p2(a) {
      return new Promise((resolve, reject) => {
        resolve(a * 2);
      });
    }
    
    // function 3  - will be wrapped in a resolved promise by .then()
    function f3(a) {
     return a * 3;
    }
    
    // promise function 4
    function p4(a) {
      return new Promise((resolve, reject) => {
        resolve(a * 4);
      });
    }
    
    const promiseArr = [p1, p2, f3, p4];
    runPromiseInSequence(promiseArr, 10)
      .then(console.log);   // 1200
    
  8. 功能型函数管道

    // Building-blocks to use for composition
    const double = x => x + x;
    const triple = x => 3 * x;
    const quadruple = x => 4 * x;
    
    // Function composition enabling pipe functionality
    const pipe = (...functions) => input => functions.reduce(
        (acc, fn) => fn(acc),
        input
    );
    
    // Composed functions for multiplication of specific values
    const multiply6 = pipe(double, triple);
    const multiply9 = pipe(triple, triple);
    const multiply16 = pipe(quadruple, quadruple);
    const multiply24 = pipe(double, triple, quadruple);
    
    // Usage
    multiply6(6); // 36
    multiply9(9); // 81
    multiply16(16); // 256
    multiply24(10); // 240
    
[1, 2, 3].includes(2);    // true
[1, 2, 3].includes(4);    // false
[1, 2, 3].includes(3, 3);  // false
[1, 2, 3].includes(3, -1); // true
[1, 2, NaN].includes(NaN); // true
arrayLike: 想要转换成数组的伪数组对象或可迭代对象
mapFn: 如果指定了该参数,新数组中的每个元素会执行该回调函数
thisArg: 可选参数,执行回调函数 mapFn 时 this 对象

console.log(Array.from('foo'));
// Array ["f", "o", "o"]

console.log(Array.from([1, 2, 3], x => x + x));
// Array [2, 4, 6]
Array.of(7);       // [7] 
Array.of(1, 2, 3); // [1, 2, 3]

Array(7);          // [ , , , , , , ]
    注意:这是指一个有7个空位(empty)的数组,而不是由7个undefined组成的数组
Array(1, 2, 3);    // [1, 2, 3]
var array1 = ['a', 'b', 'c', 'd', 'e'];

// copy to index 0 the element at index 3
console.log(array1.copyWithin(0, 3, 4));
// expected output: Array ["d", "b", "c", "d", "e"]

// copy to index 1 all elements from index 3 to the end
console.log(array1.copyWithin(1, 3));
// expected output: Array ["d", "d", "e", "d", "e"]
var array1 = ['a', 'b', 'c'];

var iterator1 = array1.entries();

console.log(iterator1.next().value);
// expected output: Array [0, "a"]

console.log(iterator1.next().value);
// expected output: Array [1, "b"]
var array1 = [1, 2, 3, 4];

// fill with 0 from position 2 until position 4
console.log(array1.fill(0, 2, 4));
// expected output: [1, 2, 0, 0]

// fill with 5 from position 1
console.log(array1.fill(5, 1));
// expected output: [1, 5, 5, 5]

console.log(array1.fill(6));
// expected output: [6, 6, 6, 6]
// 简单案例
var array1 = [5, 12, 8, 130, 44];

var found = array1.find(function(element) {
  return element > 10;
});

console.log(found);
// expected output: 12

// 更多场景
var array2 = [{ id: 1, name: 'John' }, { id: 2, name: 'Tom' }, { id: 3, name: 'Amy' }];

var found = array2.find(function(element) {
  return element.id === 2;
});

console.log(found);
// expected output: { id: 2, name: 'Tom' }
// 简单使用
var array1 = [5, 12, 8, 130, 44];

var found = array1.findIndex(function(element) {
  return element > 10;
});

console.log(found);
// expected output: 1

// 更多场景
var array2 = [{ id: 1, name: 'John' }, { id: 2, name: 'Tom' }, { id: 3, name: 'Amy' }];

var found = array2.findIndex(function(element) {
  return element.id === 2;
});

console.log(found);
// expected output: 1
// 扁平化嵌套数组
var arr1 = [1, 2, [3, 4]];
arr1.flat(); 
// [1, 2, 3, 4]

var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]

var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]

//使用 Infinity 作为深度,展开任意深度的嵌套数组
arr3.flat(Infinity); 
// [1, 2, 3, 4, 5, 6]

// 扁平化与移除数组空项
var arr4 = [1, 2, , 4, 5];
arr4.flat();
// [1, 2, 4, 5]

替代方案1: 一层嵌套

var arr1 = [1, 2, [3, 4]];
arr1.flat();

// 反嵌套一层数组
arr1.reduce((acc, val) => acc.concat(val), []);// [1, 2, 3, 4]

// 或使用 ...
const flatSingle = arr => [].concat(...arr);

替代方案2: 无限层嵌套

// 使用 reduce、concat 和递归无限反嵌套多层嵌套的数组
var arr1 = [1,2,3,[1,2,3,4, [2,3,4]]];

function flattenDeep(arr1) {
   return arr1.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val), []);
}
flattenDeep(arr1);
// [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]

替代方案3: 使用stack嵌套

// 不使用递归,使用 stack 无限反嵌套多层嵌套数组
var arr1 = [1,2,3,[1,2,3,4, [2,3,4]]];
function flatten(input) {
  const stack = [...input];
  const res = [];
  while (stack.length) {
    // 使用 pop 从 stack 中取出并移除值
    const next = stack.pop();
    if (Array.isArray(next)) {
      // 使用 push 送回内层数组中的元素,不会改动原始输入 original input
      stack.push(...next);
    } else {
      res.push(next);
    }
  }
  // 使用 reverse 恢复原数组的顺序
  return res.reverse();
}
flatten(arr1);// [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]
var array1 = ['a', 'b', 'c'];
var iterator = array1.keys();

for (let key of iterator) {
  console.log(key); // expected output: 0 1 2
}
const array1 = ['a', 'b', 'c'];
const iterator = array1.values();

for (const value of iterator) {
  console.log(value); // expected output: "a" "b" "c"
}
var new_array = arr.flatMap(function callback(currentValue[, index[, array]]) {
    // 返回新数组的元素
}[, thisArg])
var arr1 = [1, 2, 3, 4];

arr1.map(x => [x * 2]); 
// [[2], [4], [6], [8]]

arr1.flatMap(x => [x * 2]);
// [2, 4, 6, 8]

// 只会将 flatMap 中的函数返回的数组 “压平” 一层
arr1.flatMap(x => [[x * 2]]);
// [[2], [4], [6], [8]]

flatMap和flat区别:

let arr = ["今天天气不错", "", "早上好"]

arr.map(s => s.split(""))
// [["今", "天", "天", "气", "不", "错"],[""],["早", "上", "好"]]

arr.flatMap(s => s.split(''));
// ["今", "天", "天", "气", "不", "错", "", "早", "上", "好"]

等价于:归纳(reduce)与合并(concat)

var arr1 = [1, 2, 3, 4];

arr1.flatMap(x => [x * 2]);
// 等价于
arr1.reduce((acc, x) => acc.concat([x * 2]), []);
// [2, 4, 6, 8]

2 Boolean对象

new Boolean([value]): 布尔值的对象包装器
Boolean(): 其他类型转换为布尔值

注意:上面两种方式不能搞混
if (new Boolean(0)) {
    // 代码执行,对象为真
}

if (Boolean(0)) {
    // 代码不执行
}

自身属性:

Boolean.length:1
Boolean.prototype: Boolean构造函数的原型对象

继承的属性和方法

Boolean.prototype.toString(): 返回字符串"true"或者"false"
Boolean.prototype.valueOf(): 返回Boolean对象的原始值

3 Date对象

new Date()
new Date(Unix 时间戳)
new Date(dateString):注意这种格式的兼容性
new Date(year, monthIndex, day, hours, minutes, seconds, milliseconds)

注意:
1. 将Date作为构造函数使用,得到Date对象
2. 将Date作为常规函数调用,返回字符串,非Date对象
3. month从0-11,代表1-12月
4. 如果传入的值超过合理范围,相邻的数值会自动调整
    13月=>下一年的1月
    70分钟=>下一个小时的10分钟
5. 上面第四种方式,前两个参数必须传递,后面如果没有值,默认为1(天)或者0(时分秒毫秒)
6. UTC:格林威治时间,Locale:本地时间

属性:

  1. Date.prototype: 允许为Date对象添加属性
  2. Date.length: 7

方法:

  1. Date.now(): 返回自 1970-1-1 00:00:00 UTC(世界标准时间)至今所经过的毫秒数。
  2. Date.parse(): 解析一个表示日期的字符串,并返回从 1970-1-1 00:00:00 所经过的毫秒数。
  3. Date.UTC(): 接受和构造函数最长形式的参数相同的参数(从2到7),并返回从 1970-01-01 00:00:00 UTC 开始所经过的毫秒数。

所有Date实例继承Date.prototype

Date.prototype方法

  1. d.getDate()/d.getUTCDate(): 获取第几天(1-31)

  2. d.getDay()/d.getUTCDay(): 获取星期的第几天(0-6)

  3. d.getFullYear()/d.getUTCFullYear(): 获取指定日期对象的年份

  4. d.getHours()/d.getUTCHours(): 获取小时数

  5. d.getMilliseconds()/d.getUTCMilliseconds(): 获取毫秒数

  6. d.getMinutes()/d.getUTCMinutes(): 获取分钟数

  7. d.getMonth()/d.getUTCMonth(): 获取月份(0-11)

  8. d.getSeconds()/d.getUTCSeconds: 获取毫秒数(0-59)

  9. d.getTime(): 返回从1970-1-1 00:00:00 UTC(协调世界时)到该日期经过的毫秒数,对于1970-1-1 00:00:00 UTC之前的时间返回负值。

上述所有的get方法都对应他们的set方法

  1. d.setDate(): 设置每月的第几天(1-31)
  2. d.setFullYear(): 设置指定年份
  3. d.setHours(): 设置小时数
  4. d.setMilliseconds(): 设置毫秒数
  5. d.setMinutes(): 设置分钟数
  6. d.setMonth(): 设置月份(0-11)
  7. d.setSeconds(): 设置毫秒数(0-59)
  8. d.setTime(): 通过指定从 1970-1-1 00:00:00 UTC 开始经过的毫秒数来设置日期对象的时间,对于早于 1970-1-1 00:00:00 UTC的时间可使用负值。

其他方法:

  1. d.toDateString():返回日期部分字符串
  2. d.toLocaleDateString():返回一个表示该日期对象日期部分的字符串,该字符串格式与系统设置的地区关联。
  3. d.toLocaleTimeString():返回一个表示该日期对象时间部分的字符串,该字符串格式与系统设置的地区关联。
  4. d.toLocaleString():返回一个表示该日期对象的字符串,该字符串格式与系统设置的地区关联。
  5. d.toString():返回一个表示该日期对象的字符串。
  6. d.valueOf():返回一个日期对象的原始值(时间戳)

4 Math对象

Math不是构造器,所有的属性和额方法都是静态的。

属性

方法

function rand(m,n){
    return Math.floor(Math.random()*(n-m+1)+m);
}
三角函数是以弧度返回值的,通过除法Math.PI/180把弧度转换为角度,也可以通过其他方法转换。

5 Number对象

主要功能:用来执行类型转换。

属性:

方法:

6 String对象

属性:

方法

var str = 'I`m 16';
str.match(/\d+/); // ["16", index: 4, input: "I`m 16", groups: undefined]
上一篇 下一篇

猜你喜欢

热点阅读