JavaScript常用方法总结 -【干货】

138 阅读12分钟

一、JS 检测对象类型

1. typeof

  • 一般用做区分基本数据类型
    typeof 0;  //number;
    typeof true;  //boolean;
    typeof undefined;  //undefined;
    typeof "hello world"   //string;
    typeof function(){};   //function;

    typeof null; //object
    typeof {};  //object;
    typeof []; //object

2. Object.prototype.toString.call

    console.log(Object.prototype.toString.call(new Date)) // [object Date]
    console.log(Object.prototype.toString.call(JSON)) // [object JSON]
    console.log(Object.prototype.toString.call(Math)) // [object Math]
    console.log(Object.prototype.toString.call(new f)) // [object Object]
    console.log(Object.prototype.toString.call(f)) // [object Function]

要拿到一个对象的类型字符串,可以这么写:

function type(obj) { return Object.prototype.toString.call(obj).slice(8, -1)}
console.log(type(new Date)); // Date

1和2混用检测

    function ifType(val){
      let type  = typeof val;
      if (type !== "object") {    // 先进行typeof判断,如果是基础数据类型,直接返回
        return type;
      }
      // 对于typeof返回结果是object的,再进行如下的判断,正则返回结果
      return Object.prototype.toString.call(obj).slice(8, -1);
    }

3. instanceof

  • 一般用来判断数组和对象,无法检测基本数据类型
  • new 一个对象,那么这个新对象就是它原型链继承上面的对象了,通过 instanceof 我们能判断这个对象是否是之前那个构造函数生成的对象,这样就基本可以判断出这个新对象的数据类型
    var o = { };
    var a = ['reg','blue'];

    o instanceof Object; // true
    o instanceof Array;  // false

    a instanceof Array;   // true
    a instanceof Object; // true
    
    
    let Fn = function () { }
    let gs = new Fn()
    console.log(gs instanceof Fn); // true
    let gcs = new String('Mercedes Gs')
    console.log(gcs instanceof String); // true
    let str = 'string'
    console.log(str instanceof String); // false

手写instanceof

思路分析:

function A() {}
var a = new A()
console.log(a.__proto__ === A.prototype); // true
  1. 基本类型直接false
  2. a._proto_ === A.prototype // true 直接返回 true
  3. 如果是原型对象没有 while再向原型链想上找 直到null 没有返回false
         function myInstanceOf(obj, fn) {
            // 基本类型直接false
            if (!['function', 'object'].includes(typeof obj) || obj === null) {
                return false
            }
            let objProto = obj.__proto__, fnPrototype = fn.prototype
            while (objProto !== fnPrototype) {
                // 再到原型对象(fnPrototype)向上的原型链去找  直到null
                objProto = objProto.__proto__
                if (objProto === null) {
                    return false
                }
            }
            return true
        }

        // 测试代码
        var a = ['reg', 'blue'];
        a instanceof Array;   // true
        a instanceof Object; // true

        console.log(myInstanceOf(a, Array));  // true
        console.log(myInstanceOf(a, Object)); // true

4. constructor

  1. 除了 null 和 undefined,constructor 可以正确检测出原始类型和对象(引用)类型。
  2. 由于我们可以随意修改 constructor 导致检测结果不准确,所以这种方法是不安全的。
        let num = 1
        let str = "123"
        let bool = false
        let arr = [1, 2, 3]
        let obj = { name: '张三', age: 22 }
        let fn = function () { }
        console.log(num.constructor === Number)
        console.log(str.constructor === String)
        console.log(bool.constructor === Boolean)
        console.log(arr.constructor === Array)
        console.log(obj.constructor === Object)
        console.log(fn.constructor === Function)

        String.prototype.constructor = 'aaa'
        console.log(str.constructor === String)

二、字符串常用方法

  • 获取字符串长度 length

1. 获取字符串指定位置的值

charAt()和charCodeAt()

       //charAt 返回指定字符,下标超出范围返回空字符串。 不改变原字符串 参数:下标默认0
         const str = 'hello';
         console.log(str.charAt(2)); // ? l
         console.log(typeof str.charAt(5)); // ? 空字符串
         
       //charCodeAt 返回指定字符的ASCII十进制码
        const str = 'hello';
        console.log(str.charCodeAt(2)); // ? 108
        console.log(str.charCodeAt(5)); // ? NAN

2. 检索字符串是否包含特定序列

2.1 indexOf和lastIndexOf

  • indexOflastIndexOf 查看字符串是否包含给定的字符串,有返回出现的下标 没有返回-1
  • 不管从前往后还是从后往前检索下标始终从左往右
  • 参数①检索的val(必传)参数② 从哪开始(可选)
  • 参数②取负数都从下标0开始
  • indexOf 返回第一次出现的下标;lastIndexOf 返回最后一次出现的下标
  • lastIndexOf给参数②则从右向左检索
    'Blue Whale'.indexOf('Blue')      // 返回  0
    'Blue Whale'.indexOf('Blute')     // 返回 -1
    'Blue Whale'.indexOf('Whale', 0)  // 返回  5
    'Blue Whale'.indexOf('Whale', 5)  // 返回  5
    'Blue Whale'.indexOf('Whale', 7)  // 返回 -1
    'Blue Whale'.indexOf('Whale', -3)  // 返回 5
    
    'canal'.lastIndexOf('a');     // 3
    'canal'.lastIndexOf('a', 2);  // 1
    'canal'.lastIndexOf('a', 0);  // -1
    'canal'.lastIndexOf('x');     // -1
    'canal'.lastIndexOf('c', -5); // 0
    'canal'.lastIndexOf('c', 0);  // 0

2.2 includes

  • includes 是否包含子串 返回布尔值 不改变原字符串
  • 参数①要查找的字符串; 参数②从那个位置开始查找,默认为 0
    const str = "To be, or not to be, that is the question.";

    console.log(str.includes("To be")); // true
    console.log(str.includes("question")); // true
    console.log(str.includes("nonexistent")); // false
    console.log(str.includes("To be", 1)); // false
    console.log(str.includes("TO BE")); // false
    console.log(str.includes("")); // true

2.3 startsWith和endsWith

  • startsWithendsWith 查看是否以给定的字串开头或结尾 返回布尔值 不改变原字符串
  • startsWith 参数② 从哪里开始默认0
  • endsWith 参数② 到哪里结束
        var str = "To be, or not to be, that is the question.";
        alert(str.startsWith("To be")); // true
        alert(str.startsWith("not to be")); // false
        alert(str.startsWith("not to be", 10)); // true
        alert(str.startsWith("be", 3)) // true

        var str = "To be, or not to be, that is the question.";
        alert(str.endsWith("question.")); // true
        alert(str.endsWith("to be")); // false
        alert(str.endsWith("to be", 19)); // true
        alert(str.endsWith("be", 5)); // true

3. 字符串的拼接concat

  • 参数可以是多个要拼接的字符串逗号隔开,也可是一个数组
  • + 也可以拼接字符串
    let hello = 'Hello, '
    console.log(hello.concat('Kevin', '. Have a nice day.'))
    // Hello, Kevin. Have a nice day.

    let greetList = ['Hello', ' ', 'Venkat', '!']
    "".concat(...greetList)  // "Hello Venkat!"

    "".concat({})    // [object Object]
    "".concat([])    // ""
    "".concat(null)  // "null"
    "".concat(true)  // "true"
    "".concat(4, 5)  // "45"

4. 字符串截取

4.1 slice

  • 截取字符串的一部分, 返回新字符串,不改变原字符串
  • 包含起始不包含结束索引的元素
    var str1 = 'The morning is upon us.', // str1 的长度 length 是 23。
        str2 = str1.slice(1, 8),
        str3 = str1.slice(4, -2),
        str4 = str1.slice(12),
        str5 = str1.slice(30);
    console.log(str2); // 输出:he morn
    console.log(str3); // 输出:morning is upon u
    console.log(str4); // 输出:is upon us.
    console.log(str5); // 输出:""
    
    var str = 'The morning is upon us.';
    str.slice(-3);     // 返回 'us.'
    str.slice(-3, -1); // 返回 'us'
    str.slice(0, -1);  // 返回 'The morning is upon us'

4.2 substring

  • 包含起始不包含结束索引的元素
  • 如果 indexStart 等于 indexEndsubstring 返回一个空字符串。
  • 如果省略 indexEndsubstring 提取字符一直到字符串末尾。
    let str = 'Mozilla';
    console.log(str.substring(0, 3)); //Moz
    console.log(str.substring(1,1)); // ''
    console.log(str.substring()); // Mozilla
    console.log(str.substring(3,0));  //Moz

4.3 substr

  • 截取字符串的一部分, 返回新字符串,不改变原字符串
  • 参数①indexStart 参数②需要截取的个数
    var str = "abcdefghij";

    console.log("(1,2): "    + str.substr(1,2));   // (1,2): bc
    console.log("(-3,2): "   + str.substr(-3,2));  // (-3,2): hi
    console.log("(-3): "     + str.substr(-3));    // (-3): hij
    console.log("(1): "      + str.substr(1));     // (1): bcdefghij
    console.log("(-20, 2): " + str.substr(-20,2)); // (-20, 2): ab
    console.log("(20, 2): "  + str.substr(20,2));  // (20, 2):

5. 字符串替换replace和replaceAll

  • 返回替换后的字符串 不改变原字符串
        let text = 'cat , bat , sat , fat';
        let result = text.replace('at', 'ond');
        console.log(result); // ? cond , bat , sat , fat

        result = text.replace(/at/g, 'ond');
        console.log(result); //=> ? cond , bond , sond , fond

        console.log('aabbcc'.replaceAll('b', '.')); // aa..cc

6. 字符串分割成数组split

  • 参数① 以啥分割 ; 参数② 分割返回元素个数
        let color = 'red,blue,yellow,black';
        let color1 = color.split(',');
        console.log(color1); // ['red', 'blue', 'yellow', 'black']
        let color2 = color.split(',', 2);
        console.log( color2); //  ['red', 'blue']

7. 大小写转换

  • toLowerCase 大->小
  • toUpperCase 小->大
     // console.log('a2c'.toUpperCase()); // A2C
     // console.log('D5F'.toLowerCase()); // d5f

8. 去除空格

trim(两端) || trimStart(开头) || trimEnd(末端) 返回新串

        let str1 = " aoo ";
        let str2 = " boo ";
        let str3 = " coo ";
        console.log(str1.trim().length); // 3
        console.log(str2.trimStart().length); // 4
        console.log(str3.trimEnd().length); // 4

三、数组常用方法

1. 元素插入

  • array.push(): 末尾添加元素,返回新数组的长度,改变原数组
  • array.unshift(): 头部添加元素,返回新数组的长度,改变原数组
  • array.splice(): 任意位置添加元素,返回新数组,改变原数组

splice方法增加元素 参数①插入的位置;参数②必须是0;参数③插入的元素

        var arr = [1, 2, 3];
        var res = arr.push(6, 7, 8);
        console.log(res); // ?  6
        console.log(arr); // ?  [1, 2, 3, 6, 7, 8]
        
        var arr = [1, 2, 3];
        var res = arr.unshift(6, 7, 8);

        console.log(res); // ? 6
        console.log(arr); // ? [6, 7, 8, 1, 2, 3]
        
        var arr = [1, 2, 3, 4, 5, 6, 7];
        var res = arr.splice(2, 0, 8, 9); 
        // var res = arr.splice(2, 0, ...[8, 9]); 
        console.log(res); // ? []
        console.log(arr); // ? [1, 2, 8, 9, 3, 4, 5, 6, 7]

2. 元素删除

  • array.pop(): 末尾删除元素,返回被删除的元素,改变原数组
  • array.shift(): 头部删除元素,返回被删除的元素,改变原数组
  • array.splice(): 任意删除元素,返回被删除的元素数组,改变原数组
        var arr = [1, 2, 3];
        var res = arr.pop();

        console.log(res); // ? 3
        console.log(arr); // ? [1, 2]
        
        var arr = [1, 2, 3];
        var res = arr.shift();

        console.log(res); // ? 1
        console.log(arr); // ? [2, 3]
        
        var res = arr.splice(1); // 只传第一个参数,表示删除的起点 删除的元素包含开始下标元素,到最后一个元素
        console.log(res); // ? [2, 3, 4, 5, 6, 7]
        console.log(arr); // ? [1]
        
        var res = arr.splice(2, 3); // 两个参数, 从第几个开始删,包含起始元素,第二个参数是删除几个
        console.log(res); // ? [3, 4, 5]
        console.log(arr); // ? [1, 2, 6, 7]

3. 数组的拼接concat

         var arr = [1, 2, 3];
         var res = arr.concat(1, [0, 0]); // 多个任意项,可以是数组,可以是单个项
         console.log(res); // ? [1, 2, 3, 1, 0, 0]
         console.log(arr); // ? [1, 2, 3] 

4. 数组的截取slice

  • 返回截取的子数组,不改变原数组
  • 参数①开始下标,结束下标,返回的数组 [...)
    var arr = [1, 2, 3, 6, 7, 8];
    var res = arr.slice(1, 4);
    console.log(res); // ?  [2, 3, 6]
    console.log(arr); // ? [1, 2, 3, 6, 7, 8]

5. 查找数组

(1) includes

  • 查找数组中是否包含某个元素,返回布尔值,不改变原数组
  • 参数①必传,表示要查询的元素,
  • 参数②可选,表示从指定位置查起(若为负数,从后查起,负数超过数组长度,则置为 0)
        var arr = [1, 2, 3];
        var res = arr.includes(2);
        console.log(res); // true
        console.log(arr); // [1, 2, 3]

(2) find

  • 返回满足条件的第一个元素,不再向下查找,没满足条件的返回undefined 不改变原数组
  • 参数: callback:function(item, index, array){})
        const found = array.find(element => element > 10);
        console.log(found); // ? 12
        console.log(array); // ? [5, 12, 8, 130, 44]

(3) findIndex

  • 返回满足条件的第一个元素的索引,不在向下查找,没满足条件的返回-1 不改变原数组
  • 参数: callback:function(item, index, array){})
        const array = [5, 12, 8, 130, 44];
        const found = array.findIndex(element => element > 10);

        console.log(found); // ? 1
        console.log(array); // ? [5, 12, 8, 130, 44]

6. 清空数组

  • array.length 为 0
  • array.splice(0)
  • array = []
    const colors = ['blue', 'green', 'black'];
    colors.length = 0;
    colors; // []
    
    const colors = ['blue', 'green', 'black'];
    colors.splice(0);
    colors; // []
    
    const colors = ['blue', 'green', 'black'];
    colors = [];
    colors; // []

7. 数组翻转(改变原数组)

         var arr = [1, 2, 3, 3, 4, 5, 5, 7, 9]
         console.log(arr.reverse()) // ? [9, 7, 5, 5, 4, 3, 3, 2, 1]
         console.log(arr) // ? [9, 7, 5, 5, 4, 3, 3, 2, 1] 

7. sort(改变原数组)

callback:(a, b) => a - b 口诀: a-b升,b-a降

         var arr = [1, 3, 9, 2, 5, 3, 7, 4, 5];

        var res1 = arr.sort((a, b) => a - b);
        console.log(res1) // ? [1, 2, 3, 3, 4, 5, 5, 7, 9]

        var res2 = arr.sort((a, b) => b - a);
        console.log(res2) // ? [9, 7, 5, 5, 4, 3, 3, 2, 1]

        console.log(arr) // ? [9, 7, 5, 5, 4, 3, 3, 2, 1]

8. join

将数组的所有元素连成一个指定分隔符的字符串并返回,不改变原数组

        var arr = [1, 2, 3, 3, 4, 5, 5, 7, 9];
        console.log(arr.join('-')); // ? '1-2-3-3-4-5-5-7-9'
        console.log(arr); // [1, 2, 3, 3, 4, 5, 5, 7, 9]

9. 数组的遍历

(1) for

        var arr = [1, 2, 3];
            for (let i = 0; i < arr.length; i++) {
                // ...
                console.log("continue 打断当次循环,进入下次循环");
                console.log("break  直接打断循环,跳出循环");
        } 

(2) forEach (改变元素组)

        const array1 = ['a', 'b', 'c'];
        array1.forEach((item, index) => console.log(item, index));

(3) for..of

    const colors = ['blue', 'green', 'white'];

    for (const color of colors) {
      console.log(color);
    }

(4) map

  • 创建由callback返回值组成的新数组,不改变原数组
         const array1 = [1, 4, 9, 16];
         const map1 = array1.map(x => {
             if (x > 4) {
                 return x * 2
             }
             return x
         });
         console.log(map1); // ? [1, 4, 18, 32]
         console.log(array1); // ? [1, 4, 9, 16] 

(5) Array.from()

        let arr = [2, 4, 6];
        const result = Array.from(arr, (item) => {
            return item * 2
        })
        console.log(result); // [4, 8, 12]
        console.log(arr);    // [2, 4, 6]

(6) filter 过滤(不改变原数组)

        let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        let res = nums.filter(num => num >5);
        console.log(res); // [6, 7, 8, 9, 10]

(7) every 不改变原数组

每一个元素是否都满足callback的筛选条件,返回布尔值

        let arr = [1, 2, 3, 4, 5]
        console.log(arr.every((item, index, array) => item > 3)) // ? false

(8) some 不改变原数组

数组中是否有一个满足callback的筛选条件,返回布尔值

        let arr = [1, 2, 3, 4, 5]
        console.log(arr.every((item, index, array) => item > 3)) // ? true

(9) reduce 累计相关的数组处理

  • 参数①:callback(初始值,当前值,当前索引),
  • 参数②可选: 给定初始值,如果不给 处理的数组第一个元素为初始值,当前索引从1开始
        // 1. 数组求和
        let sum = [0, 1, 2, 3].reduce((accumulator, currentValue) => {
            return accumulator + currentValue;
        }, 0);
        console.log(sum); // ? 6

        // 2. 数组去重
        let arr = ['a', 'b', 'a', 'b', 'c', 'e', 'e', 'c', 'd', 'd'];
        let newArr = arr.reduce((acc, current) => {
            if (!acc.includes(current)) {
                acc.push(current);
            }
            return acc;
        }, []);
        console.log(newArr); // ? ['a', 'b', 'c', 'e', 'd']

        // 3. 数组扁平化
        let flat = [
            [1, 2, 3],
            [4, 5, 6],
            [7, 8, 9]
        ].reduce((prev, cur, index, array) => {
            return [...prev, ...cur];
        });
        console.log(flat); //  [1, 2, 3, 4, 5, 6, 7, 8]

(10) fill 数组填充 改变原数组

  • 参数:①填充固定值、②起始位、③终止位
  • 填充范围填充给定的值,包含起始位不包含截止位
        let arr = [1, 2, 3, 4]
        console.log(arr.fill(-1, 1, 3)); // [1, -1, -1, 4]
        
        // 多用于创建指定长度的空数组填充
        // let arr1 = new Array(3)
        // arr1.fill(1) // arr1 = [1, 1, 1]

Array.from

        const emptyObjects = Array.from(Array(4), function () {
            return {};
        });
        console.log(emptyObjects);; // [{}, {}, {}, {}]

(11) flat数组扁平化

用于扁平化数组或去除空项,返回新数组,不改变原数组

        let arr1 = [1, 2, [3, 4]];
        newArr1 = arr1.flat();
        console.log(newArr1); // ? [1, 2, 3, 4]
        
        //使用 Infinity,可展开任意深度的嵌套数组
        // let arr3 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
        // newArr3 = arr3.flat(Infinity);
        // console.log(arr3, newArr3); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        
        // 去除空项
           let arr4 = [1, 2, , 4, 5];
           newArr4 = arr4.flat();
           console.log(arr4, newArr4); // ? [1, 2, empty, 4, 5] (4) [1, 2, 4, 5]

四、对象常用方法

1. Object.create() 创建对象

创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。 它接收两个参数,不过第二个可选参数是属性描述符(不常用,默认是undefined)。

    var anotherObject = {
        name: '小明'
    };
    var myObject = Object.create(anotherObject, {
        age: {
            value:18,
        },
    });
    // 获得它的原型
    Object.getPrototypeOf(anotherObject) === Object.prototype; // true 说明anotherObject的原型是Object.prototype
    Object.getPrototypeOf(myObject); // {name: "小明"} // 说明myObject的原型是{name: "若川"}
    myObject.hasOwnProperty('name'); // false; 说明name是原型上的。
    myObject.hasOwnProperty('age'); // true 说明age是自身的
    myObject.name; // '小明'
    myObject.age; // 18;

1. Object.assign() 合并对象

  • Object.assign(target, ...sources)

target: 接收源对象属性的对象,也是修改后的返回值 sources: 源对象,包含将被合并的属性。

注意: 如果源对象目标对象存在相同属性,则源对象覆盖目标对象属性

    // 对象的浅拷贝
    const obj = { a: 1 };
    const copy = Object.assign({}, obj);
    console.log(copy); // { a: 1 }
    
    // 对象的合并
    let target = { name: 'nike', age: '20' }
    let source = { address: '郑州', gender: '男', name: 'LLL' }
    Object.assign(target, source)
    console.log(target) //{name: 'LLL', age: '20', address: '郑州', gender: '男'}

2. hasOwnProperty() 判断自身是否包含检测属性

  • obj.hasOwnProperty(prop)
    o = new Object();
    o.hasOwnProperty('prop'); // 返回 false
    o.prop = 'exists';
    o.hasOwnProperty('prop'); // 返回 true
    delete o.prop;
    o.hasOwnProperty('prop'); // 返回 false

3. getOwnPropertyNames() 获取自身所有的属性

  • Object.getOwnPropertyNames(obj)
     var obj = { name: '张三', age: 18 }
     console.log(Object.getOwnPropertyNames(obj));

4. Object.getPrototypeOf() 获取指定对象的原型

        class Point {
                constructor(x, y) {
                    this.x = x;
                    this.y = y;
                }

                toString() {
                    return '(' + this.x + ', ' + this.y + ')';
                }
            }

        var point = new Point(2, 3);
        console.log(point.__proto__); //{constructor: ƒ, toString: ƒ}
        console.log(Object.getPrototypeOf(point)); //{constructor: ƒ, toString: ƒ}

5. Object.freeze() 冻结对象

  • 不能添加新属性
  • 不能删除已有属性
  • 不能修改已有属性的值
  • 不能修改原型
  • 不能修改已有属性的可枚举性、可配置性、可写性
        var obj = {
            name: '张三',
            age: 18,
            address: '上海市'
        }
        obj.__proto__.habit = '运动'

        // 冻结对象
        Object.freeze(obj)

        // 不能添加新属性
        obj.sex = '男'
        console.log(obj)    // {name: "张三", age: 18, address: "上海市"}

        // 不能删除原有属性
        delete obj.age
        console.log(obj)    // {name: "张三", age: 18, address: "上海市"}

        // 不能修改已有属性的值
        obj.name = '李四'
        console.log(obj)    // {name: "张三", age: 18, address: "上海市"}

        // 不能修改原型
        obj.__proto__ = '随便什么值'
        console.log(obj.__proto__)  // {habit: "运动", constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, …}

        // 不能修改已有属性的可枚举性、可配置性、可写性
        Object.defineProperty(obj, 'address', { // TypeError: Cannot redefine property: address
            enumerable: false,
            configurable: false,
            writable: true
        })