# 5. 引用类型

# 5.1 Object类型

  • 创建对象的两种方式
    • 创建对象实例: new Object()
    • 对象字面量: {}

# 5.2 Array类型

  • 创建数组的方式

    • new Array()
    • 数组字面量 []
  • 将数组的length属性进行修改, 如果length值小于数组长度, 则会把多余的移除, 如果length值大于数组长度, 会使用undefined补充

  • 检测数组

    • instanceOf
    • Array.isArray()
  • 数组的转换方法

    • toString(): 会按照,进行拼接成字符串返回
    • valueOf(): 返回的是数组
  • 数组方法

    • join()
    • push()
    • pop()
    • shift()
    • unshift()
    • reverse()
    • sort(): sort方法只会比较字符串
    • concat(): 返回新数组
    • slice(): 返回新数组
    • splice(): 修改原数组
    • indexOf()
    • lastIndexOf()
    • every()
    • filter()
    • forEach()
    • map()
    • some()
    • reduce()
    • reduceRight()
  • 函数名实际上也是一个指向函数对象的指针

  • JavaScript函数没有重载, 相同命名的函数, 后者会覆盖前者

  • 函数声明和函数表达式的区别: 函数声明有函数声明提升的过程

  • 函数内部属性:

    • arguments
    • this
  • 函数属性和方法:

    • length: 参数的个数
    • prototype: 内部属性不可使用for...in枚举
    • apply: 天生就有的, 不是继承来的, 第二参数可以是数组也可以是arguments
    • call: 天生就有的, 不是继承来的
  • apply和call真正的作用是扩充函数作用域

  • 基本包装类型:

    • String()
    • Boolean()
    • String()
var str = 'some text';
var str2 = str.subString(2); 

// 正常情况下, str是基本类型, 没有subString()方法, 但当读取基本类型的值时, 会自动为字符串进行包装类, 一旦执行完毕, 会立即销毁
// var str = new String('some text');
// var str2 = s1.subString(2);
// str = null;

// 同理 Boolean() 和 Number()
  • 所有基本类型的对象在转换为bool类型时都是true

# 5.4 RegExp类型

  • (1)创建一个正则表达式
const expression = /pattern/flags;
  • (2) flags有3个标志

    • g: 全局模式, 即模式将被应用于所有字符串, 而非在发现第一个匹配项时立即停止;
    • i: 不区分大小写模式, 即在确定匹配项时忽略模式与字符串的大小写;
    • m: 多行模式, 即在到达一行文本末尾时还会继续查找下一行中是否存在与模式匹配的项
  • (3) 量词

    • n+: 表示至少有一个前导字符n, 前导字符是符号前面的一个字符
    • n*: 表示前导字符n个数不限
    • n?: 表示0或1个前导字符n
    • n{X}: 表示包含X个n的序列的字符串
    • n{X|Y}: 表示包含X到Y个n的序列的字符串, 包含X和Y个
    • n{X,}: 表示包含至少X个n的序列的字符串
    • n$: 匹配任何结尾为n的字符串, 从末尾开始匹配
    • ^n: 匹配任何开头为n的字符串
    • ^n$: 表示只匹配字符串n, 也就是匹配整个字符串

    例如:

    const str = 'php phhhhp pp phhp';
    
    const result = str.match(/ph+p/g);  // ["php", "phhhhp", "phhp"]
    
    const result = str.match(/ph*p/g);  // ["php", "phhhhp", "pp", "phhp"]
    
    const result = str.match(/ph?p/g);  // ["php", "pp"]
    
    const result = str.match(/aa/g);    // null
    
    const result = str.match(/ph{2}p/g);  // ["phhp"]
    const result = str.match(/ph{2,}p/g); // ["phhhhp", "phhp"]
    const result = str.match(/ph{2,4}p/g);// ["phhhhp", "phhp"]
    
    const result = str.match(/^php/g);      // ["php"]
    const result = str.match(/^php$/g);      // ["php"]
    
  • (4)元字符

    • .: 表示单个字符, 表示任意字符, 除了换行和换行符
    • .*: 表示任意字符串(0个或多个任意字符, 除了换行和行结束符)
    • \w: 匹配任意数字, 字母, 下划线
    • \W: 匹配任何非数字, 非字母, 非下划线
    • \d: 查找数字
    • \D: 查找非数字字符
    • \s: 查找空白字符
    • \S: 查找非空白字符
    • \b: 匹配单词边界
    • \B: 匹配非单词边界
    • \n: 查找换行符
    • \r: 查找回车符
    • \t: 查找制表符
  • (5) 方括号 方括号表示一个范围, 也称为字符簇

    • [abc] 查找方括号之内的任何字符
    • [^abc] 查找任何不在方括号之间的字符 (方括号中^表示取反)
    • [0-9] 查找任何从0-9的数字, 表示一个字符
    • [a-z] 查找任何从小写a到z的字符
    • [A-Z] 查找任何从大写a到z的字符
    • [A-z] 查找任何从大写A到小写z的字符, 包括下划线
    • [5-8] 查找5-8的字符
    • (red)|(blue)|(green) 查找任何指定的选项
  • (6) 捕获和引用 先用小括号()捕获, 然后用\1引用

    • \1: 表示引用第1个小括号里捕获的值
    • \2: 表示引用第2个小括号里捕获的值
    • (?:): 禁止引用
  • (7) 匹配中文

    • [4E00-9FA5]: 中文编码从4E00开始, 到9FA5结束
    const str = 'hello 中国';
    const result = str.match(/[\u4e00-\u9fa5]/);
    console.log(result); // ['中', '国']
    
  • (8) 环视(断言/零宽断言)

    • regexp(?=n): 匹配任何其后紧接指定字符串n的字符串
    • regexp(?!n):匹配任何其后没有紧接指定字符串n的字符串
    // 有一个字符串是"abcdacd", 从里面查找a, 并且是其后紧接b的a
    const str = /a(?=b)/g;
    
    // 有一个字符串是"abcdacd", 从里面查找a, 且其后不是紧接b的a
    const str = /a(?!b)/g;
    
    // 查询连续的字母, 要求字母的后面必须是数字
    const str = 'php7 esnext hello中国';
    const result = str.match(/[a-zA-Z]+(?=\d|[\u4e00-\u9fa5])/g);
    console.log(result); // ["php", "hello"]
    
    • (?!B)regexp: 前置的(?!B)只是对后面数据的一个限定, 从而达到过滤匹配的效果
    // 表示一个字符串可以由数字字母组成, 但不能全是数字
    const str = '12312312afarf';
    const result = str.match(/(?!^\d+$)^[0-9a-zA-Z]+$/g);
    console.log(result);
    

# 5.4.1 RegExp实例属性

  • global: 是否设置了g标志
  • ignoreCase: 是否设置了i标志
  • multiline: 是否设置了m标志
  • source: 正则表达式的字符串表示
  • lastIndex: 开始搜索下一个匹配项的字符位置, 从0算起

# 5.4.2 RegExp实例方法

  • exec(): 返回包含第一个匹配项的数组
  • test(): 检测目标字符串和正则表达式是否匹配, 如果匹配返回true, 不匹配返回false
  • valueOf(): 返回正则表达式本身
  • toString(): 返回正则表达式字面量形式
  • toLocalString(): 返回正则表达式字面量形式

面试题:

// 表示一个字符串可以由数字字母组成, 但不能全是数字
const str = '今今今今今今今今今今今今晚上吃吃吃吃吃鸡鸡鸡鸡';
const result = str.replace(/([\u4e00-\u9fa5])\1+/g, '$1');
console.log(result);

# 5.6.2 Number类型

  • 创建Number对象
var numberObj = new Number(10);
  • Number类型也重写了valueOf(), toLocaleString(), toString()

    • valueOf()返回基本类型的数值
    • toString(n)返回n进制数值的字符串形式
  • Number类型还提供了将数值格式化为字符串的方法

    • toFixed(n) 保留小数点后n位
  • 使用 new 调用的基本包装类型的构造函数, 与直接调用同名的转型函数式不一样的

var value = "25";
var number = Number(value); //转型函数
alert(typeof number); //"number"

var obj = new Number(value); // 构造函数
alert(typeof obj);

# 5.6.3 String类型

String类型是字符串的对象包装类型, 可以通过new String()来构建

  • String 类型的属性和方法
    • length
    • charAt(1) 返回当前位置的字符
    • charCodeAt(1) 返回对应位置的字符编码
    • fromCharCodeAt() 接受一个或多个编码字符, 然后拼接成字符串, 与charCodeAt()相反
    • concat()
    • slice()
    • split()
    • subStr()
    • subString()
    • indexOf()
    • lastIndexOf()
    • trim()
    • toUpperCase()
    • toLowerCase()
    • replace()
    • search()
    • match()

还可以通过`[]`来访问某个字符

const str = '12312'
console.log(str[0])

# 5.7.1 Global对象

  • Global(全局)对象是不存在的(浏览器中是window代替), 它不存在任何其他对象的属性和方法, 最终都是它的属性和方法,所谓全局作用域定义的属性和函数, 都是Global对象的属性

  • Global对象的方法

    • isNaN()
    • isFinite()
    • parseInt()
    • parseFloat()
    • encodeURI()
    • encodeURIComponent()
    • decodeURI()
    • decodeURIComponent()
  • encodeURI()与encodeURIComponent()区别:

    • encodeURI()不会对本身属于URI的特殊字符进行编码, 只会对空格进行编码
    • encodeURIComponent()则会对所有的特殊字符进行编码
  • eval()中创建的任何变量或者函数都不会被提升

# 5.7.2 Math对象

  • Math对象的方法
    • max()
    • min()
    • ceil()
    • floor()
    • round()
    • random()

找出数组中最大值

const values = [1, 2, 3, 4, 5];
const max = Math.max.apply(this, values);