JS引用类型介绍(二)
-
引用类型是js中非常重要的一种数据格式,js赋予了这种数据格式非常强大的属性以及方法,而且也给出了很大的扩展空间,这使得之后的框架可以在此基础上发展起来
Js中给出的引用类型分为7类,本篇将介绍RegExp类型,Function类型
RegExp类型
使用RegExp类型来支持正则表达式
let expression = /pattern/ flags;
支持3个flag标志位
- g:全局模式,并非遇到一个匹配项就停止(global)
- i:不区分大小写(case-insensitive)
- m:多行模式(multiline)
pattern的内容比较负责,具体见这篇博客
RegExp实例属性
通过属性可以取得关于模式的各种信息
let parttern = /
at/i; let parttern1 = new RegExp("\ [bc\]at","i"); //global:布尔值,是否设置g标志 alert(parttern.global); //flase //ignoreCase: 布尔值,是否设置i位 alert(parttern.ignoreCase); //ture //multiline: 布尔值,是否设置m位 alert(parttern.multiline); //flase //lastIndex: 整数,表示开始搜索下一个匹配项的字符位置,从0算起 alert(parttern.lastIndex); //0 //source: 正则表达式的字符串表示,按照字面量形式返回 alert(parttern.source); //"[bc]at" alert(parttern1.source); // " at" RegExp实例方法
- exec()
专门为捕获组而设计,接受一个参数(字符串),返回包含第一个匹配信息的数组,没有匹配项是返回null。虽然返回的是数组实例,但是包含两个额外的属性,index和input
let text = "cat, bat, sat, fat"; let pattern1 = /.at/; let pattern2 = /.at/g; let matches1 = pattern1.exec(text); alert(matches1.index); //0 匹配项在字符串中的位置 alert(matches1.input); //"cat,bat,sat,fat" 输入字符串 alert(matches1[0]); //"cat" let matches2 = pattern2.exec(text); alert(matches2.index); //0 alert(matches2.input); //"cat,bat,sat,fat" alert(matches2[0]); //"cat" alert(pattern2.lastIndex); //3 matches2 = pattern2.exec(text); alert(matches2.index); //5 alert(matches2[0]); //"bat" alert(pattern2.lastIndex); //8
- test()方法
接受一个字符串参数,检测目标字符串是否与某个模式匹配,常用在if语句中
let test = "000-0000-0000"; let pattern = /\d{3}-\d{4}-d{4}/; if(pattern.test(text)){ //匹配 }
- valueOf(),toString(),toLocaleString()
valueOf()方法返回正则表达式本身
toString()方法返回正则表达式的字面量
toLocaleString()方法返回正则表达式的字面量
RegExp构造函数属性
括号内为缩写
- input(
$_) ——最近一次要匹配的字符串 - lastMatch($&) ——最近一次的匹配项
- lastParen(
$+) ——最近一次匹配的捕获组 - leftContext($`) ——input字符串中lastMatch之前的字符串
- rightContext(
$') ——input字符串中lastMatch之后的字符串 - multiline($*) ——是否采用多行模式
let text = "this has been a short summer"; let patern = /(.)hort/g; if(pattern.test(text)){ alert(RegExp.input); //this has been a short summer alert(RegExp.lastMatch); //short alert(RegExp.lastParen); //s alert(RegExp.leftContext); //this has been a alert(RegExp.rightContext); //summer alert(RegExp.multiline); //flase }
模式的局限性
RegExp存在一定的局限性,有很多不支持的特性
Function类型
函数实际上是对象,每个函数都是Function的实例,函数是对象,函数名是指针。
函数可以通过++函数声明++语法定义也可以通过++函数表达式++定义函数//函数声明语法定义 function sum (num1, num2){ return num1 + num2; } //函数表达式定义 let sum = function(num1, num2){ return num1 + num2; }
通过函数声明创建的函数会函数声明提升,而通过函数表达式创建的函数只有在执行到所在的代码行时才会被执行。
没有重载(深入理解)
创建两个函数名相同的函数,后面的函数会覆盖前面的函数
作为值的函数
函数名本身就是变量,所以函数也可以作为值来使用
function callSomeFunction(someFunction,someArgument){ return someFunction(someArgument); } function add(num){ return num+10; } let result = callSomeFunction(add, 10); //20,当要访问函数指针而不执行函数的话,需要用add而不是add()
也可以从函数中返回另一个函数,典型例子:根据对象属性对对象进行排序
function creatComparisonFunction(propertyName){ return function(object1,object2){ let value1 = object1[propertyName]; let value2 = object2[propertyName]; return value1-value2; } } let data = [{ name: "Z", age: 12 },{ name: "N", age: 18 }]; data.sort(creatComparisonFunction("name")); alert(data[0].name); //N data.sort(creatComparisonFunction("age")); alert(data[0].name); //Z
函数内部属性
函数内部有两个特殊的对象:arguments和this
arguments除了保存参数之外,还有一个callee的属性,该属性是一个指针,指向拥有这个arguments的函数//阶乘 function factorial(num){ if(num <= 1){ return 1; }else{ return num * factorial(num-1); } } //使用callee属性可以解除紧密的耦合关系现象 function factorial(num){ if(num <= 1){ return 1; }else{ return num * arguments.callee(num-1); } }
this引用的是函数执行的环境对象
ES5规范了另外一个函数对象的属性:caller,该属性保存着调用当前函数的函数的引用,caller属性不能被赋值function outer(){ inner(); } function inner(){ alert(inner.caller); //alert(arguments.callee.caller); } outer(); //执行后显示outer()函数的源代码
函数属性和方法
既然函数是对象,那函数也拥有属性和方法
函数拥有两个属性:- lengh(函数希望接受参数的数量)
- prototype(保存所以的实例方法,之后详细介绍)
函数包含两个非继承的方法:
- apply()
- call()
两个函数的作用都是在特定的作用域(this)调用函数
function sun(num1, num2){ return num1 + num2; } function callSum1(num1, num2){ return sum.apply(this, arguments); } function callSum2(num1, num2){ return sum.apply(this, [sum1, sum2]); } function callSum3(num1, num2){ return sum.call(this, sum1, sum2) } console.log(callSum1(10,10)); //20 console.log(callSum2(10,10)); //20 console.log(callSum3(10,10)); //20
两个函数的强大之处是它们可以扩充函数赖以生存的作用域
window.color = "red"; let o = {color: "blue"}; function sayColor(){ alert(this.color); } // 不同的作用域 sayColor(); //"red" sayColor(this); //"red" sayColor(window); //"red" sayColor(o); //"blue"
另外,函数还有一个方法:bind()
该方法会创建一个函数实例,其this值会绑定到传给bind()函数的值