2017.12.11-学习笔记:js进阶知识点整理

2017.12.11-学习笔记:js进阶知识点整理_第1张图片

前言:古人云,温故而知新,把自己学习js的进阶笔记整理一下,有错误之处还望指出,谢谢。

→点我去看js基础知识点整理

→点我去看jQuery知识点整理

→点我去看dom知识点整理

JavaScript进阶

1.typeof:
  • 1.返回的是一个字符串;
  • 2.只能判断简单数据类型,复杂数据类型用instanceof
  • 3.是一个关键字,不是一个函数,()的作用:提升优先级;
  • 4.如果是一个函数,返回的是function,函数在js里是一等公民;
  • 5.如果是null,返回的是object。
2.逻辑运算符:
  • 逻辑中断:
    && : 找假值, 从左往右依次判断,如果某个操作数的逻辑是false,中断。
    || : 找真值, 从左右往右依次判断,如果某个操作的逻辑是true,中断。

  • 转换成布尔类型是false的几种情况:
    null undefined 0 NaN "" false

    • 补充:null 和 undefined
      • null 是一个表示“无”的对象,转为数值时为 0;undefined 是一个表示“无”的原始值,转为数值时是NaN

      • 当声明的变量还未被初始化时,变量的默认值为 undefined。null 用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象。

      • undefined 表示“缺少值”,就是此处应该有一个值,但是还没有定义。典型用法是:
        1.变量被声明了,但没有赋值时,就等于 undefined
        2.调用函数时,应该提供的参数没有提供,该参数等于 undefined
        3.对象没有赋值的属性,该属性的值为 undefined
        4.函数没有返回值,默认返回 undefined

      • null 表示“没有对象”,即该处不应该有值。典型用法是:
        1.作为函数的参数,表示该函数的参数不是对象
        2.作为对象原型链的终点

  • 使用场景:

function animate(fn) {
  fn && fn(); //如果传参数函数就执行函数
}
animate();
3.比较运算符:
  • == 的转换规则:
    1. NaN 不等于任何值 包括NaN本身
    2. null 不等于任何值, 除了null 和 undefined
    3. undefined不等于任何值, 除了undefined本身和null
    4. 如果两边有布尔类型, 两边都转换成数值类型比较 false:0 true:1
    5. 如果两边有数值类型, 两边都转换成数值类型。
    6. 如果两边没有数字和布尔类型,有字符串,都转换成字符串比较。
    7. 如果两边都是对象,比地址。
      Number( [ 空数组 ] )为 0 ;Number( { 空对象 } )为 NAN。
4.严格模式:
  • 开启严格模式:’’use strict’’
    1.变量必须声明;
    2.禁止this指向window对象;
    3.禁用八进制。
5.数据类型:
  • 简单数据类型:值类型,存储的是值本身;
  • 复杂数据类型:引用类型,存储的是对象的地址,复制的地址,对象只有一个,两个变量指向同一个对象。
6.拷贝:
  • 浅拷贝:将对象中所有的属性都依次赋值到新对象里面去。浅拷贝只复制了一层对象的属性
    如果对象中的属性还有对象,那浅拷贝只能复制该对象的地址,所以复制后该属性的对象和原属性的对象是同一个。

  • 深拷贝:判断原对象的属性值的数据类型是否为对象typeof obj[k] === 'object'
    利用递归 temp[k] = cloneObj(obj[k]); 实现。

7.对象:无序的键值对的集合。
  • 面向过程:员工,一步一步考虑做事的过程;
    面向对象:老板,让谁做什么事。
    面向对象是面向过程的封装,而不是替代。

  • 面向对象的三大特性:

    • 1.封装:
      函数:封装一段代码。
      对象: 把一些属性和函数封装到一个对象了。
    • 2.继承:
      拿来主义:一个对象没有这个属性或者方法,另一个对象有个这个属性或者方法,通过某些手段,能够直接用另一个对象的属性和方法。
    • 3.[多态]:js中没有,只有强类型语言有。
  • 创建对象的方式:

var obj = new Object();

var obj={}; // 字面量创建;

//工厂函数:每次调用,都会创建出来一个对象。
function createPhone(brand) {
  var obj = {
    brand: brand
  }
  return obj;
}
// 缺点:创建出来的对象全是object类型,无法区分。

/*构造函数:实例化对象
  1. 首字母大写
  2. 作用: 实例化对象(给this添加属性和方法)
  3. 配合new关键字使用,如不配合new,this指向window*/
function Phone(brand) {
  this.brand = brand;
}
// 缺点:内存浪费;改进:用原型'
var hw = new Phone("华为");
  • new关键字:
    1. 在内存开辟一块新的空间,创建一个空的对象
    2. 让构造函数的this指向这个新的对象
    3. 调用构造函数
    4. 返回新对象。
8.prototype:原型对象
    1. 所有的函数(构造函数)都会自带一个属性:prototype 这个属性的值是一个对象: 原型对象。
    2. 通过构造函数实例化的对象 可以直接访问prototype属性(原型对象)的属性和方法。
  • 构造函数中相同的属性和方法可以放入其对应的原型对象中。
    对象: 存储每个不一样值 (name, age , gender)
    原型:存储所有对象共同的东西(方法)

  • 所有的函数都会有一个属性:prototype 指向其 原型对象
    所有的对象都会有一个属性:_proto_ 指向当前对象的构造函数的 prototype 属性。
    所有的原型对象都会有一个属性:constructor 指向当前 构造函数

  • 属性搜索原则:
    如果自己有,用自己的,如果没有,找对象._proto_,如果还没有,一直往上找,知道Object.prototype,如果没有,undefined。

9.原型链:
  • 一个对象会有一个原型(对象._proto_),同时这个原型也是一个对象,这个原型也会有原型,一环扣一环,就形成了一个链式的结构,我们把这个链式结构叫做;原型链

  • 对象可以使用原型上的东西,也可以使用原型的原型的东西,对象可以使用整个原型链上的东西。

1.var p = new Person();
p-- > Person.prototype-- > Object.prototype-- > null

2.var arr = [];
arr-- > Array.prototype-- > Object.prototype-- > null

3.var date = new Date();
date-- > Date.prototype-- > Object.prototype-- > null

4.var obj = {}
obj-- > Object.prototype-- > null

5. Math对象
Math-- > Object.prototype-- > null
10.Object.prototype的成员:
  • obj.hasOwnProperty(prop) :判断prop属性是否是obj自己提供
    in操作符:如果属性不是自己提供的,是从原型上继承来的,也会返回true

  • obj.propertyIsEnumerable(prop) : 判断prop是否是自己的属性, prop属性可否遍历

  • obj1.isPrototypeOf(obj2): 判断obj1是否在obj2原型链上。

  • toString(): Object.prototype.toString() [object type] 将对象转换成字符串

  • toLocaleString():跟本地化有关,

  • valueOf() : 将对象转换成简单类型(数值、布尔)

11.沙箱:匿名函数自调用
  • 优点:不用担心全局变量污染的问题
    缺点:完全与外界隔绝
    对外暴露变量:传递window作为参数传入,window.变量=变量
12.继承:让一个对象可以使用另一个对象的属性和方法。
  • 混入式继承:(jQuery的extend继承)
var jQuery = {
  extend: function(temp) {
    for (var k in temp) {
      if(temp.hasOwnProperty(k)){
        this[k] = temp[k];
      }
    }
  }
}
var class = {
  addClass:function(){}
}
jQuery.extend(class)
  • 原型式继承:
    一个对象可以访问构造函数的原型中的属性和方法,那么如果想要让一个对象增加某些属性和方法,只需要把这些属性和方法放到原型对象中即可。
// 1.直接给原型增加属性和方法

// 2.原型替换(jQuery的原型替换)
jQuery.prototype = {
  constructor: jQuery,
  version: "1.0.0",
  extend: function(temp) {
    for (var k in temp) {
      if(temp.hasOwnProperty(k)){
        this[k] = temp[k];
      }
    }
  }
}


// 3.mixin+原型:不换原型,给原型混入
class = {
  addClass:function(){}
}
jQuery.prototype.extend = function(temp) {
  for (var k in temp) {
    if(temp.hasOwnProperty(k)){
      this[k] = temp[k];
    }
  }
}
jQuery.prototype.extend(class)
  • 经典继承:
    ES5提供了一个方法: Object.create(obj);
    返回值:一个新的对象
    参数: 一个对象,这个对象会成为新对象的原型对象
var lw = {
  money: 1000000,
  car: "劳斯莱斯"
}
var newObj = Object.create(lw);
  • 如何安全的扩展内置对象:
    需求:要给所有创建的数组增加一个方法,sayHi的方法
    注意:永远不要去修改内置对象。
function MyArray() {}
MyArray.prototype = new Array() / [空数组];
MyArray.prototype.push = function() {
  console.log("hehe");
}
var arr = new MyArray();
arr.push();
var arr2 = new Array();
console.log(arr2.push(1, 2, 3));
13.函数进阶
  • 定义函数:
    • 1.函数声明:function fn(){}
      函数声明会提升,因此可以先调用,后声明
      函数声明:必须要有名字 ()里面只能出现表达式
      !function( ){ }( );等同于匿名函数自调用

    • 2.函数表达式:var fn = function() {}
      函数表达式只会将函数名提升,所以只能在赋值后调用函数

    • 3.构造函数的方式 function是复杂类型
      Object:内置构造函数,用来创建对象的
      Function:内置构造函数,用来创建函数的
      参数: arg1,arg2,arg3.....body
      1. 所有的参数都是字符串
      2. 前面可以指定任何多个形参,最后一个参数是代码体

    var fn1 = new Function("a1", "a2", "alert(a1+a2)");
    fn1(1,2);//3
14.eval的作用:
  • 将一段字符串当成代码来执行。eval("alert(1+2)");
  • 代码编辑器:
button.onclick = function() {
  var content = txt.value;
  eval(content);
}
  • eval 让一个json字符串转换成js对象。
15.json:
  • 一种通过的数据交换的格式,就是一个字符串,只不过这个字符串有一定的规则。
    var json = '{"name": "zs", "age": 18, "sex": "男"}';

  • 把json字符串转换成js对象:
    var obj = JSON.parse(json);
    参数:json字符串
    返回值:js对象

  • 把js对象转换成json字符串:
    var json = JSON.stringify(obj);

  • eval也可以把一个json字符串转换成js对象(少用)
    var json = '{"name": "zs", "age": 18, "sex": "男"}';
    eval会把字符串当成js代码来解析
    var obj = eval("(" + json + ")"); //{}不止有对象的意思,还有代码块的意思

16.this的指向:
  • 函数:当一个函数不是一个对象的属性时,我们称之为函数。
    方法:当一个函数被保存为对象的一个属性时,我们称之为方法。

  • this:
    1.函数调用模式:this指向的是window
    2.方法调用模式:this指向调用当前方法的对象
    3.构造函数调用模式:如果函数是new调用的,此时this被绑定到创建出来的新对象上
    4.上下文调用模式:call、apply

    • Call:
      可以调用一个函数,并且可以指定这个函数的this指向
      第一个参数可以指定函数内部的this指向
      fn.call(thisArg, arg1, arg2, arg3);==fn(arg1, arg2, arg3)
    • Apply:
      apply()方法的作用和 call()方法类似,只有一个区别,就是apply()方法接受的是数组或者伪数组, 里面存放了所有的参数列表。而call()方法接受的是若干个参数的列表。
      apply有一个特性:平铺特性, apply会把数组里面的每一项都当成参数。
      fn.apply(thisArg, [arg1, arg2, arg3]);==fn(arg1, arg2, arg3)

    5.bind:创建一个新的函数, 可以绑定新的函数的this指向
    返回值:新的函数
    参数:新函数的this指向,当绑定了新函数的this指向后,无论使用何种调用模式,this都不会改变。
    var newFn = fn.bind(window);

17.伪数组:
  • 1.伪数组其实就是一个对象,但是跟数组一样,伪数组也会有length属性,也有0,1,2,3等属性。

  • 2.伪数组并没有数组的方法,不能使用push/pop等方法

  • 3.伪数组可以跟数组一样进行遍历,通过下标操作。

  • 4.常见的伪数组:arguments、document.getElementsByTagName的返回值、jQuery对象

  • 5.伪数组借用数组的方法:Array.prototype/ [ ].push.call(arrLike, "赵六");

  • 6.将伪数组转换成真数组:var arr = Array.prototype/ [ ].slice.call(arrLike);或者通过es6let arr = [...arrLike]

18.完整版原型链:
  • 函数是由new Function创建出来的,因此函数也是一个对象, 所有的函数都是new Function的实例。
2017.12.11-学习笔记:js进阶知识点整理_第2张图片
完整版原型链

2017.12.11-学习笔记:js进阶知识点整理_第3张图片
原型链神图.jpg
  • 总结:
    所有函数都是new Function创建出来的,因此所有函数._proto都是Function.prototype
    所有对象都是new Object创建出来的,因此所有对象._proto
    都是Object.prototyp
19.ECMAScript族谱
2017.12.11-学习笔记:js进阶知识点整理_第4张图片
ECMAScript族谱
  • Function.prototype成员:
    1.arguments:获取函数的实参,被函数内部的arguments替代了。//只能在函数内部用,es6中用rest代替
    2.length:获取形参的长度
    3.name:获取函数的名字,此属性不允许修改
    4.caller:用于获取当前在函数是在哪个函数中调用的,已经被废弃了。
    5.constructor:指向当前构造函数,Function
    6.call:调用函数,重新指向this
    7.apply:调用函数,重新指向this
    8.bind:重新指向this,返回一个新的函数,不调用。
    arguments使用场景://只能用于函数内部,相当于函数内部的属性
/*jQuery的css方法
设置单个样式:.css(name, value)
设置多个样式:.css(obj)
获取样式.css(name)*/

function css() {
  if (arguments.length === 2) {
    console.log("要执行设置单个样式的操作");
  }
  if (arguments.length === 1) {
    var temp = arguments[0];
    if (typeof temp === "object") {
      console.log("要执行设置多个样式的操作");
    }
    if (typeof temp === "string") {
      console.log("要执行的是获取样式的操作");
    }
  }
}

function max() {
  return Math.max.apply(Math, arguments);
}
console.log(max(1, 2, 3, 4, 55, 6, 7, 8, 9));// 55
20.字面量和变量

字面量(直接量):从字面的意思就能看出来类型和值 55 "abc" true [] {},浏览器能够直接显示字面量。
变量:可以变化的量, 必须要先声明,才能使用, 如果变量没有声明,浏览器不认识,就会报错。

21.预解析:
  • 1.函数优先,先提升函数,再提升变量
  • 2.如果有同名的变量,会直接忽略
  • 3.如果有同名的函数,会覆盖
22.作用域:
  • 作用域:变量起作用的区域,作用域决定了 一个变量该定义在哪里,该如何获取
    全局变量: 定义在函数外面的变量,全局变量,特点:在任何地方都可以访问
    局部变量: 定义在函数内部的变量,局部变量,特点:只有在当前函数内部才可以使用

  • js的作用域: 静态作用域(词法作用域)
    查找变量的时候,变量的在函数声明的时候,作用域就已经定下来了。
    查找变量的时候,看的是函数的声明,不管哪里调用
    如果函数声明是在代码块{}里面的话, 函数的名字会提升,但是函数体不提升。
    不要在代码块里面声明函数。用函数表达式

  • 全局作用域:只要页面不关闭(卸载),全局作用域会一直存在,全局变量
    函数作用域:函数调用时,就会形成一个函数作用域,内部的变量都是局部变量,函数调用结束时,函数作用域就释放了,局部变量就释放。

  • 变量的搜索原则
    从当前作用域向上找,如果一个变量不存在,获取这个变量的值会报错xxx is not defined;,给这个变量设置值,那么设置变量就是隐式全局变量。
    函数传形参=函数内部var 形参。

  • 面试题

//作用域面试题1:
var num = 10;
fn1();

function fn1() {
  console.log(num);
  var num = 20;
  console.log(num);
}
console.log(num);

//作用域面试题2:
var num1 = 10;
var num2 = 20;

function fn(num1) {
  num1 = 100;
  num2 = 200;
  num3 = 300;
  console.log(num1); //100
  console.log(num2); //200
  console.log(num3); //300
  var num3;
}
fn();
console.log(num1); //10  100
console.log(num2); //200
console.log(num3); //报错

//作用域面试题3:
fn3();
console.log(c); //9 undefined
console.log(b); //9 
console.log(a); //报错

function fn3() {
  var a = b = c = 9;
  console.log(a); //9
  console.log(b); //9
  console.log(c); //9
}

//作用域面试题4:
var num = 1;

function fn() {
  var num = 100;
  num++;
  console.log(num);
}
fn(); //101
fn(); //101
console.log(num); //1

//作用域面试题5:
var color = "red";

function outer() {
  var anotherColor = "blue";

  function inner() {
    var tmpColor = color;
    color = anotherColor;
    anotherColor = tmpColor;
    console.log(anotherColor);
  }
  inner();
}
outer();
console.log(color); //red blue

//This面试题1:
var obj = {
  sayHi: function() {
    console.log(this);
  }
}
var fn = obj.sayHi;
fn(); //请问打印结果是什么?

//This面试题2:
var fn = function() {
  console.log(this);
}
var obj = {
  sayHi: fn
}

//This面试题3:
var age = 38;
var obj = {
  age: 18,
  getAge: function() {
    console.log(this.age); //???
    function foo() {
      console.log(this.age); //????
    }
    foo();
  }
}
obj.getAge();
23.递归函数:函数内部直接或者间接的调用自己
    1. 函数直接或者间接自己调用自己
    2. 递归一定要有结束的条件(死递归)
  • 化归思想:
// 1.计算1-n之间所有数的和
function getSum(n) {
  if (n == 1) {
    return 1;
  }
  return getSum(n - 1) + n;
}
console.log(getSum(100));

// 2.计算斐波那契数列
var arr = [];
function fib(n) {
  if (n == 1 || n == 2) {
    return 1;
  }
  return fib(n - 1) + fib(n - 2);
}
console.log(fib(100));

var n1 = 1;
var n2 = 1;
var num = 0;
for (var i = 3; i <= 12; i++) {
  num = n1 + n2;
  n1 = n2;
  n2 = num;
}
console.log(num);
  • 递归实现深拷贝
24.闭包:
  • 为何需要闭包:
    在js中,函数会形成函数作用域,在函数内部可以直接访问全局变量,在函数外部却无法访问函数内部的变量;在函数内部有一个函数,那么函数内部的函数是可以访问到外部函数的变量的。闭包就是能够读取到其他函数内部变量的函数。

  • 定义在函数内部的函数,用来连接函数内部与外部的桥梁。

  • 闭包应用:

//1.计数器:
function outer() {
  var count = 0;

  function add() {
    count++;
    console.log("当前count" + count);
  }
  return add;
}
var result = outer();
result();

//2.私有变量的读取和设置:
function outer() {
  var num = 10;

  function set_num(n) {
    num = n;
  }

  function get_num() {
    return num;
  }
  return {
    set_num: set_num,
    get_num: get_num
  }
}
var obj = outer();
obj.set_num(2000);
console.log(obj.get_num());

//3.实现缓存:
//缓存(cache):数据的缓冲区,当要读取数据时,先从缓冲中获取数据,
                                       //如果找到了,直接获取,
                                       //如果找不到,重新去请求数据。
function outer() {
  //缓存
  var arr = [];
  var fbi = function(n) {
    if (n == 1 || n == 2) {
      return 1;
    }
    if (arr[n]) {
      return arr[n];
    } else {
      var temp = fbi(n - 1) + fbi(n - 2);
      arr[n] = temp; //存入缓存
      return temp;
    }
  }
  return fbi;
}
var fbi = outer();
console.log(fbi(40));
  • Js垃圾回收机制:

引用记数垃圾收集:如果没有引用指向某个对象(或者是函数作用域),那么这个对象或者函数作用域就会被垃圾回收机制回收。

var o = {
  name:"zs"
}
//对象被o变量引用  ,引用记数1
var obj = o;   //变量被o和obj引用,引用记数2

o = 1;  //o不在引用对象了, 引用记数1
obj = null; //obj不在引用对象了,引用记数0,可以被垃圾回收了。

闭包占用内存释放:

function outer(){
  var count = 0;

  function fn(){
    count++;
    console.log("执行次数"+count);
  }
  return fn;
}

var result = outer();
result();
result = null;//当函数fn没有被变量引用了,那么函数fn就会被回收,
              //函数fn一旦被回收,那么outer调用形成的作用域也就得到了释放。
  • 闭包面试题:
打印当前按钮对应的下标:
第一种:使用let定义变量   es6  let特点:{}也能形成作用域
var btns = document.querySelectorAll("button");
for (let i = 0; i < btns.length; i++) {
  btns[i].onclick = function () {
    console.log(i);
  }
}

第二种: 使用属性存储下标
var btns = document.querySelectorAll("button");
for (var i = 0; i < btns.length; i++) {
  btns[i].index = i;
  btns[i].onclick = function () {
    console.log(this.index);
  }
}

第三种: 使用forEach遍历
var btns = document.querySelectorAll("button");
btns.forEach(function (e, i) {
  //e:是每一个元素   i:每一个下标
  btns[i].onclick = function () {
    console.log(i);
  }
});

第四种:闭包解决
var btns = document.querySelectorAll("button");
for (var i = 0; i < btns.length; i++) {
  (function (num) {
    btns[num].onclick = function () {
      console.log(num);
    }
  })(i);//调用btns.length-1次匿名函数,每次调用都产生相应的函数作用域,
        //在每个相应的函数作用域中给注册事件赋值一个函数
}

第五种:
var btns = document.querySelectorAll("button");
for (var i = 0; i < btns.length; i++) {
  btns[i].onclick = (function (num) {
    function fn() {
      console.log(num);
    }
    return fn;
  })(i);//给btn注册btns.length-1次事件赋值,每次注册调用匿名函数产生相应的函数作用域
}


使用setTimeout  每秒钟打印一个数字  0, 1, 2,3,4,5,6,7,8,9
第一种:let
for(let i = 0; i < 10; i++){
  setTimeout(function () {
    console.log(i);
  }, i * 1000 )
}

第二种:闭包
  for(var i = 0; i < 10; i++){
    (function (num) {
      setTimeout(function () {
        console.log(num);
      }, num * 1000)
    })(i);
  }

第三种:闭包
for(var i = 0; i < 10; i++){
  var fn = (function (i) {
    return function(){
      console.log(i);
    }
  })(i);
  setTimeout(fn, i * 1000);
}
25.正则表达式:js中常用于表单验证。
  • 创建
    1.构造函数的方式:var regExp = new RegExp(/\d/);
    2.正则字面量:var regExp = /\d/;
    3.正则的使用:/\d/.test("aaa1");

  • 普通字符:abc

  • 元字符:具有特殊意义的字符
    \d: 数字
    \D: 非数字
    \w: 单词字符 a-zA-Z0-9_
    \W: 非单词字符
    \s: 不可见字符 空格 \t \n
    \S: 可见字符
    . : 任意字符 (\n)
    \.: 匹配.
    |: 或 优先级最低
    (): 优先级最高的
    []: 一个字符的位置,里面是可以出现的字符
    [^] :^表示非
    ^表示开始
    $表示结束
    ^$ 表示精确的匹配
    *表示 出现0次或者0次以上
    + 表示 1次或者1次以上
    ?表示 0 次 或者 1次
    {n,m} 出现n次到m次 * {0,} + {1,} {0,1}
    {n,} 出现n次或者n次以上
    {n} 出现n次

  • 常见验证
    var phoneReg = /^0\d{2,3}-\d{7,8}$/;
    var qqReg = /^[1-9]\d{4,11}$/;
    var mobileReg = /^1[345789]\d{9}$/;
    var nameReg = /^[\u4e00-\u9fa5]{2,4}$/;
    var emailReg = /^\w+@\w+(.\w+)+$/;

  • 正则的参数: /\d/g :global 全局的 i: ignore:忽略大小写

  • 字符串替换

题1:var str = "   123AD  asadf   asadfasf  adf  ";
①.把所有 ad 换成 xx
str = str.replace(/ad/g, "xx");

②.把ad /AD /aD /Ad  都换成xx
str = str.replace(/ad/gi, "xx");

③.把str中所有的空格去掉
str = str.replace(/\s/g, "");

题2:var str = "abc,efg,123,abc,123,a";
所有的逗号替换成 !
str = str.replace(/,/g, "!");

题3:var jsonStr = '[{"name":"张三",score:8},{"name":"张三",score:90},{"name":"张三",score:81}]';
把所有成绩都修改成100分
jsonStr = jsonStr.replace(/\d{1,2}/g, "100");

字符串传匹配,匹配所有分数
var reg = /\d{1,2}/g;
var arr = jsonStr.match(reg);
console.log(arr);

题4:var str = "大家好,我是xxx,我的手机号码是18511112222,我前女友的手机号码是13222221111,我的现女友的手机号码15555555555";

var reg = /1[345789]\d{9}/g;
var arr = str.match(reg);
console.log(arr);



2017.12.11-学习笔记:js进阶知识点整理_第5张图片


Knowledge changes the mind

你可能感兴趣的:(2017.12.11-学习笔记:js进阶知识点整理)