安全初级—正则表达式、This关键字、闭包

这篇具有很好参考价值的文章主要介绍了安全初级—正则表达式、This关键字、闭包。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

正则表达式

字面量字符

某个字符只表示它字面的含义,例如/a/匹配a/b/匹配b

元字符

(1)点字符(.)

点字符可以匹配除回车(\r)、换行(\n)、行分隔符(u2028)和段分隔符(\u2029)以外的所有字符。

同时,点字符对于码点大于0xFFFF字符也不能正确的匹配,会认为这是两个字符

c.t会匹配ct之间包含任意一个字符的情况,只要字符在同一行。

(2)位置字符

位置字符用来提示字符所处的位置,主要有两个字符。

  • ^ 表示字符串的开始位置
  • $ 表示字符串的结束位置
// test必须出现在开始位置
/^test/.test('test123') // true

// test必须出现在结束位置
/test$/.test('new test') // true

// 从开始位置到结束位置只有test
/^test$/.test('test') // true
/^test$/.test('test test') // false

(3)选择符(|

(|)表示“或关系”(or),即a|b匹配ab

多个选择符可以联合使用。

// 匹配fred、barney、betty之中的一个
/fred|barney|betty/

其他的元字符还包括\*+?()[]{}

转义符

正则表达式中,需要反斜杠转义的,一共有12个字符:^.[$()|*+?{\

这些有特殊含义的元字符,如果要匹配它们本身,就需要在它们前面要加上反斜杠。

特殊字符

对于不能打印的特殊字符,正则表达式提供了表达方法

  • \cX 表示Ctrl-[X],其中的X是A-Z之中任一个英文字母,用来匹配控制字符。
  • [\b] 匹配退格键(U+0008),不要与\b混淆。
  • \n 匹配换行键。
  • \r 匹配回车键。
  • \t 匹配制表符 tab(U+0009)。
  • \v 匹配垂直制表符(U+000B)。
  • \f 匹配换页符(U+000C)。
  • \0 匹配null字符(U+0000)。
  • \xhh 匹配一个以两位十六进制数(\x00-\xFF)表示的字符。
  • \uhhhh 匹配一个以四位十六进制数(\u0000-\uFFFF)表示的 Unicode 字符。

字符类

字符类(class)表示有一系列字符可供选择,只要匹配其中一个就可以了

例如[abc] 表示abc之中任选一个匹配。

(1)脱字符(^)

如果方括号内的第一个字符是[^],则表示除了字符类之中的字符,其他字符都可以匹配。

例如[^abc] 表示abc之外都可以匹配。

如果方括号内没有其他字符,即只有[^],就表示匹配一切字符,其中包括换行符。

点号作为元字符(.)是不包括换行符的

(2)连字符(-)

某些情况下,对于连续序列的字符,连字符(-)用来提供简写形式,表示字符的连续范围。

例如[123456789]可以写成[1-9],同理[A-Z]表示26个大写字母。

/a-z/.test('b') // false
/[a-z]/.test('b') // true

如果(-)中没有出现在[]中,就只是匹配字面的含义,不具备简写的作用。

只有当(-)用在[]之中,才表示连续的字符序列。

合法的字符类简写形式:

[0-9.,]
[0-9a-fA-F]
[a-zA-Z0-9-]
[1-31]  //不代表`1`到`31`,只代表`1`到`3`

连字符还可以用来指定 Unicode 字符的范围。

var str = "\u0130\u0131\u0132";
/[\u0128-\uFFFF]/.test(str)
// true

预定义模式

预定义模式指的是某些常见模式的简写方式

  • \d 匹配0-9之间的任一数字,相当于[0-9]
  • \D 匹配所有0-9以外的字符,相当于[^0-9]
  • \w 匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_]
  • \W 除所有字母、数字和下划线以外的字符,相当于[^A-Za-z0-9_]
  • \s 匹配空格(包括换行符、制表符、空格符等),相等于[ \t\r\n\v\f]
  • \S 匹配非空格的字符,相当于[^ \t\r\n\v\f]
  • \b 匹配词的边界。
  • \B 匹配非词边界,即在词的内部。

通常,正则表达式遇到换行符(\n)就会停止匹配。

重复类

模式的精确匹配次数,使用大括号({})表示。{n}表示恰好重复n次,{n,}表示至少重复n次,{n,m}表示重复不少于n次,不多于m次。

量词符

量词符用来设定某个模式出现的次数。

  • ? 问号表示某个模式出现0次或1次,等同于{0, 1}
  • * 星号表示某个模式出现0次或多次,等同于{0,}
  • + 加号表示某个模式出现1次或多次,等同于{1,}

贪婪模式

量词符默认情况下都是最大可能匹配,即匹配到下一个字符不满足匹配规则为止。这被称为贪婪模式。

var s = 'aaa';
s.match(/a+/) // ["aaa"]

非贪婪模式,即最小可能匹配。只要一发现匹配,就返回结果,不往下检查。

将贪婪模式改为非贪婪模式,可以在量词符后面加一个问号。

var s = 'aaa';
s.match(/a+?/) // ["a"]

除了非贪婪模式的加号(+?),还有非贪婪模式的星号(*?)和非贪婪模式的问号(??)。

  • +?:表示某个模式出现1次或多次,匹配时采用非贪婪模式。
  • *?:表示某个模式出现0次或多次,匹配时采用非贪婪模式。
  • ??:表格某个模式出现0次或1次,匹配时采用非贪婪模式。

修饰符

修饰符(modifier)表示模式的附加规则,放在正则模式的最尾部。

修饰符可以单个使用,也可以多个一起使用。

// 单个修饰符
var regex = /test/i;

// 多个修饰符
var regex = /test/ig;

(1)g修饰符

正则模式含有g修饰符,每次都是从上一次匹配成功处,开始向后匹配。

var regex = /b/g;
var str = 'abba';

regex.test(str); // true
regex.test(str); // true
regex.test(str); // false

因为字符串abba只有两个b,所以前两次匹配结果为true,第三次匹配结果为false

(2)i 修饰符

正则对象区分字母的大小写,加上i修饰符以后表示忽略大小写。

/abc/.test('ABC') // false
/abc/i.test('ABC') // true

(3)m 修饰符

m修饰符表示多行模式(multiline),会修改^$的行为。默认情况下(即不加m修饰符时),^$匹配字符串的开始处和结尾处,加上m修饰符以后,^$还会匹配行首和行尾,即^$会识别换行符(\n)。

/world$/.test('hello world\n') // false
/world$/m.test('hello world\n') // true

This关键字

this就是属性或方法“当前”所在的对象。

下面是一个实际的例子。

var person = {
  name: '张三',
  describe: function () {
    return '姓名:'+ this.name;
  }
};

person.describe()
// "姓名:张三"

由于对象的属性可以赋给另一个对象,所以属性所在的当前对象是可变的,即this的指向是可变的。

function f() {
  return '姓名:'+ this.name;
}

var A = {
  name: '张三',
  describe: f
};

var B = {
  name: '李四',
  describe: f
};

A.describe() // "姓名:张三"
B.describe() // "姓名:李四"

函数f内部使用了this关键字,随着f所在的对象不同,this的指向也不同。

只要函数被赋给另一个变量,this的指向就会变。

使用场合

(1)全局环境

全局环境使用this,它指的就是顶层对象window

this === window // true

function f() {
  console.log(this === window);
}
f() // true

(2)构造函数

构造函数中的this,指的是实例对象。

var Obj = function (p) {
  this.p = p;
};
//在构造函数obj,this指向p属性
var o = new Obj('Hello World!');
o.p // "Hello World!"

(3)对象的方法

如果对象的方法里面包含thisthis的指向就是方法运行时所在的对象。该方法赋值给另一个对象,就会改变this的指向。

var obj ={
  foo: function () {
    console.log(this);
  }
};

obj.foo() // obj
//此时this指向obj
//以下的用法会改变this的指向
// 情况一
(obj.foo = obj.foo)() // window
// 等同于
(obj.foo = function () {
  console.log(this);
})()
// 等同于
(function () {
  console.log(this);
})()

// 情况二
(false || obj.foo)() // window
//等同于
(false || function () {
  console.log(this);
})()

// 情况三
(1, obj.foo)() // window
//等同于
(1, function () {
  console.log(this);
})()

使用注意点

避免多层 this

由于this的指向是不确定的,所以切勿在函数中包含多层的this

var o = {
  f1: function () {
    console.log(this);
    var f2 = function () {
      console.log(this);
    }();
  }
}

o.f1()
// Object
// Window

这种情况,f1第一次指向对象o,然后代码运行到f2时,this的指向又变成了全局对象。

避免数组处理方法中的 this

数组的mapforeach方法,允许提供一个函数作为参数。这个函数内部不应该使用this

var o = {
  v: 'hello',
  p: [ 'a1', 'a2' ],
  f: function f() {
    this.p.forEach(function (item) {
      console.log(this.v + ' ' + item);
    });
  }
}

o.f()
// undefined a1
// undefined a2

上面的this其实也是类似于多层this,函数f的调用也是相当于在全局环境下调用,所以这里的this指向也是指向window对象。

避免回调函数中的 this

回调函数中的this往往会改变指向,最好避免使用。

var o = new Object();
o.f = function () {
  console.log(this === o);
}

// jQuery 的写法
$('#button').on('click', o.f);

以上的代码,在调用函数f时,是在按钮对象的环境下调用的,所以this的指向也不是o,而是指向按钮的DOM对象。

绑定 this 的方法

JavaScript 提供了callapplybind这三个方法,来切换/固定this的指向。

Function.prototype.call()

函数实例的call方法,可以指定函数内部this的指向(即函数执行时所在的作用域),然后在所指定的作用域中,调用该函数。

call方法的参数,应该是一个对象。如果参数为空、nullundefined,则默认传入全局对象。

var n = 123;
var obj = { n: 456 };

function a() {
  console.log(this.n);
}

//如果`call`方法没有参数,或者参数为`null`或`undefined`,则等同于指向全局对象。
a.call() // 123
a.call(null) // 123
a.call(undefined) // 123
//如果指向全局对象,返回结果为`123`
a.call(window) // 123
//如果使用`call`方法将`this`关键字指向`obj`对象,返回结果为`456`
a.call(obj) // 456

如果call方法的参数是一个原始值,那么这个原始值会自动转成对应的包装对象,然后传入call方法。

var f = function () {
  return this;
};

f.call(5)  //5为参数,不是对象
// Number {[[PrimitiveValue]]: 5}

call方法还可以接受多个参数。

func.call(thisValue, arg1, arg2, ...)

Function.prototype.apply()

apply方法的作用与call方法类似,也是改变this指向,然后再调用该函数。唯一的区别就是,它接收一个数组作为函数执行时的参数,使用格式如下。

func.apply(thisValue, [arg1, arg2, ...])

(1)找出数组最大元素

JavaScript 不提供找出数组最大元素的函数。结合使用apply方法和Math.max方法,就可以返回数组的最大元素。

var a = [10, 2, 4, 15, 9];
Math.max.apply(null, a) // 15

(2)将数组的空元素变为undefined

通过apply方法,利用Array构造函数将数组的空元素变成undefined

Array.apply(null, ['a', ,'b'])
// [ 'a', undefined, 'b' ]

(3)转换类似数组的对象

另外,利用数组对象的slice方法,可以将一个类似数组的对象(比如arguments对象)转为真正的数组。

Array.prototype.slice.apply({0: 1, length: 1}) // [1]
Array.prototype.slice.apply({0: 1}) // []
Array.prototype.slice.apply({0: 1, length: 2}) // [1, undefined]
Array.prototype.slice.apply({length: 1}) // [undefined]
//前提:被处理的对象必须有`length`属性,以及相对应的数字键。

Function.prototype.bind()

bind()方法用于将函数体内的this绑定到某个对象,然后返回一个新函数。

var counter = {
  count: 0,
  inc: function () {
    this.count++;
  }
};

var func = counter.inc.bind(counter);
func();
counter.count // 1

//`counter.inc()`方法被赋值给变量`func`。这时必须用`bind()`方法将`inc()`内部的`this`,绑定到`counter`,否则就会出错。

bind()方法有一些使用注意点。

(1)每一次返回一个新函数

bind()方法每运行一次,就返回一个新函数,这会产生一些问题。

(2)结合回调函数使用

回调函数是 JavaScript 最常用的模式之一,但是一个常见的错误是,将包含this的方法直接当作回调函数。

(3)结合call()方法使用

利用bind()方法,可以改写一些 JavaScript 原生方法的使用形式。

闭包

闭包就是能够读取外层函数内部变量的函数

变量作用域

变量的作用域为两种:全局作用域和局部作用域

1)函数内部可以读取全局变量

2)函数外部无法读取函数内部的局部变量

读取函数内部的局部变量

1)在函数内部再定义一个函数

function f1() {
	let code = 200;

	function f2() {
		console.log(code);
	}
}

函数f1内部的函数f2可以读取f1中所有的局部变量。因此,若想在外部访问函数f1中的局部变量code,可通过函数f2间接访问。

2)为外部程序提供访问函数局部变量的入口

function f1() {
    let code = 200;

    function f2() {
        console.log(code);
    }

    return f2;
}

f1()();  // 200

闭包概念

  • 闭包访问的变量,是每次运行上层函数时重新创建的,是相互独立的。

  • 不同的闭包,可以共享上层函数中的局部变量

使用闭包的注意点:

1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。文章来源地址https://www.toymoban.com/news/detail-617448.html

到了这里,关于安全初级—正则表达式、This关键字、闭包的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【SQL-正则】利用正则表达式进行过滤操作(常用正则表达式)

    1、由数字、26个英文字母或者下划线组成的字符串 2、非负整数(正整数 + 0 ) 3、正整数 4、非正整数(负整数 + 0) 5、负整数 6、整数 7、非负浮点数(正浮点数 + 0) 8、正浮点数 9、非正浮点数(负浮点数 + 0) 10、负浮点数 11、浮点数 12、由26个英文字母组成的字符串 13、

    2024年02月12日
    浏览(65)
  • Java 之正则表达式语法及常用正则表达式汇总

    正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为 regex、regexp 或 RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。 正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称

    2024年02月09日
    浏览(56)
  • Python正则表达式之学习正则表达式三步曲

            正则表达式描述了一种字符串匹配的模式,可以用来检查一个串的有无某子串,或者做子串匹配替换,取出子串等操作。也可以说正则表达式就是字符串的匹配规则,也可以理解为是一种模糊匹配,匹配满足正则条件的字符串。         1、数据验证(eg:表单验

    2024年02月15日
    浏览(49)
  • constexpr 关键字(常量表达式)

    constexpr用于在编译时求值,并要求在编译时就能确定其值。它通常用于声明常量表达式、函数、构造函数等,以便在编译时进行优化。 下面是一些示例说明constexpr的用法: 在这个示例中,max_size和pi都被声明为常量表达式,它们的值在编译时就已经确定。 在这个

    2024年02月22日
    浏览(31)
  • 老夫的正则表达式大成了,桀桀桀桀!!!【Python 正则表达式笔记】

    特殊字符 .^$?+*{}[]()| 为特殊字符,若想要使用字面值,必须使用 进行转义 字符类 [] [] 匹配包含在方括号中的任何字符。它也可以指定范围,例: [a-zA-Z0-9] 表示a到z,A到Z,0到9之间的任何一个字符 [u4e00-u9fa5] 匹配 Unicode 中文 [^x00-xff] 匹配双字节字符(包括中文) 在 [] 中

    2024年02月04日
    浏览(47)
  • 机器学习与数据科学-专题1 Python正则表达式-【正则表达式入门-1】

    为了完成本关任务,你需要掌握: 在 Python 中使用正则表达式; 最基础正则表达式; 正则匹配函数。 在 Python 中使用正则表达式 正可谓人生苦短,我用 Python。Python 有个特点就是库非常多,自然拥有正则匹配这种常见的库,并且此库已经嵌入在 Python 标准库中,使用起来非常

    2024年01月22日
    浏览(39)
  • 正则表达式 (用于灵活匹配文本的表达式)

    目录 . * 用于匹配任意单个字符,除了换行符。 例如使用正则表达式 a.b, 它可以匹配aab、acb、a#b 用于匹配前一个字符零次或多次。 例如,使用正则表达式 ab*c ,它可以匹配 \\\"ac\\\"、\\\"abc\\\"、\\\"abbc\\\",因为 b* 表示匹配零个或多个字符 \\\"b\\\"。所以,这个表达式可以匹配 \\\"ac\\\"(零个 \\\"b\\\"),

    2024年01月16日
    浏览(52)
  • 【编译原理】【词法分析】【正则表达式】【NFA】【DFA】【C++】正则表达式转DFA&NFA,判断字符串是否符合正则表达式的匹配算法

    显然,正则表达式、NFA、DFA的概念都很简单,所以直接上代码,注释应该解释地比较清楚, 没有万能头文件的自行替换需求库 ,如果有疑问的可以留言。 网盘链接 [自行补全]/s/1pbGT_wpB662TwFrnukXgGQ?pwd=TSIT 提取码:TSIT 原理可以参考这篇博客 传送门 本次程序由四个文件组成 文

    2024年02月11日
    浏览(72)
  • 利用正则表达式进行爬取数据以及正则表达式的一些使用方法

    Pattern:表示正则表达式 Matcher:文本匹配器,作用按照正则表达式的规则去读取字符串,从头开始读取。 在大串中去找符合匹配规则的子串。 代码示例: 需求: 把连接:https://m.sengzan.com/jiaoyu/29104.html?ivk sa=1025883i中所有的身份证号码都爬取出来。 代码示例: 需求: 把下面文

    2024年02月09日
    浏览(46)
  • 正则表达式、常用的正则

    正则表达式(Regular Expression,简称为Regex或RegExp)是用于匹配和搜索文本模式的工具。它是一个强大且灵活的字符串处理工具,可以用来检查一个字符串是否符合特定的模式,或者从一个文本中提取满足条件的部分。 在正则表达式中,可以使用不同的元字符和特殊符号来定义

    2024年02月14日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包