网络安全——web2

目录

HTTPS

基本概念

简略过程

正规示范——数字证书

Javascrip的数组

RegExp对象——正则表达式

概述

修饰符

匹配规则

字面量字符和元字符

转义符

特殊字符

字符类

预定义模式

重复类——大括号({})

量词符——?、*、+

贪婪模式——最大可能匹配

组匹配——’()’

Javascript对象

概述

键名、属性、方法、创建

对象的引用

属性的操作

属性的读取、赋值

属性的查看、删除

属性的遍历:for...in 循环


  • HTTPS

  1. 基本概念

  • 单钥匙就是对称加密,对称加密的速度快
  • 双钥匙就是非对称加密,非对称加密的速度慢
  • 非对称加密的秘钥中,公开让别人知道的就是公钥
  • 留在自己这里不让别人知道的就是私钥
  • 公钥加密,私钥解密,这个叫加密
  • 私钥加密,公钥解密,这个叫签名
  1. 简略过程

首先服务器让CA机构用私钥 J 加密自己的公钥 D,传给浏览器,这是私钥加密,公钥解密,防止公钥 D 在传输过程中被别人篡改。浏览器得到了公钥 D 之后,加密自己的对称加密的秘钥 M,传给服务器,这是公钥加密,私钥解密,这个目的是加密,为了让中间人不知道我的 M 是什么。

注:非对称加密的复杂度非常高,性能非常低,因此仅仅适合这个传递秘钥 M 的过程,数据量很小,而且仅仅一次。之后的传输,通过对称秘钥进行传输,对称加密的效率比非对称加密高出几个数量级。

  1. 正规示范——数字证书

在HTTPS中,数字证书是一种用于验证网站身份并加密通信的安全证书。数字证书由证书颁发机构(Certificate Authority,简称CA)签发,它包含了一组加密的数据,用于确认网站的真实性和可信性。当用户访问一个使用HTTPS的网站时,浏览器会接收并验证该网站的数字证书。

数字证书包含以下重要信息:

  • 公钥:其中包含一个公开密钥,用于加密浏览器和服务器之间的通信。公钥是加密的,所以其他人无法解密数据,只有服务器拥有与公钥匹配的私钥,才能解密加密的数据。
  • 网站信息:数字证书中包含有关网站的信息,如网站的名称(通常为域名),公司名称(如果是企业网站),所在地区等。这些信息用于验证网站的所有者
  • 数字签名:证书颁发机构使用自己的私钥对证书信息进行数字签名,以保证证书的真实性和完整性。浏览器使用证书颁发机构的公钥来验证数字签名的有效性。

当用户访问一个使用HTTPS的网站时,浏览器会下载网站的数字证书并检查以下事项:

  • 证书是否由受信任的证书颁发机构签发。
  • 证书是否在有效期内。
  • 网站的域名是否与证书中的域名匹配。
  • 证书中的数字签名是否有效。

详见:http://t.csdn.cn/AaiYX

  • Javascrip的数组

Array是 JavaScript 的原生对象,同时也是一个构造函数,可以用它生成新的数组

Array()作为构造函数,行为很不一致(具体这不做解释)。因此,不建议使用它生成新数组,直接使用数组字面量是更好的做法(如下)。

var arr = [1, 2];

  1. 静态方法 Array.isArray()

Array.isArray方法返回一个布尔值,表示参数是否为数组。它可以弥补typeof运算符的不足,示例如下。

var arr = [1, 2, 3];

typeof arr // "object"

Array.isArray(arr) // true

  1. 实例方法
  1. 常用

方法

描述

concat()

连接两个或更多的数组,并返回结果。

join()

把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。

pop()

删除并返回数组的最后一个元素

push()

向数组的末尾添加一个或更多元素,并返回新的长度。

reverse()

颠倒数组中元素的顺序。

shih()

删除并返回数组的第一个元素

slice()

从某个已有的数组返回选定的元素,原数组的内容不变

sort()

对数组的元素进行排序,该方法会改变原来的数组,而不会创建新的数组

splice()

删除元素,并向数组添加新元素,数组的值会发生变化,两个参数时表示删除,三个参数时,第二个参数为0,表示添加元素到对应的位置

unshih()

向数组的开头添加一个或更多元素,并返回新的长度。

toSource()

返回该对象的源代码。

toString()

把数组转换为字符串,并返回结果。

toLocaleString()

把数组转换为本地数组,并返回结果。

valueOf()

返回数组对象的原始值

  1. valueOf(),toString()——重点
  • valueOf方法是一个所有对象都拥有的方法,表示对该对象求值。不同对象的valueOf方法不尽一致,数组的valueOf`方法返回数组本身。

var arr = [1, 2, 3];

arr.valueOf() // [1, 2, 3]

  • toString方法也是对象的通用方法,数组的toString方法返回数组的字符串形式。

var arr = [1, 2, 3];

arr.toString() // "1,2,3"

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

arr.toString() // "1,2,3,4,5,6"

  • RegExp对象——正则表达式

JavaScript 的正则表达式体系是参照 Perl 5 建立的。

Perl 5是一种通用的高级编程语言,它是Perl编程语言家族中的一员。Perl最初由Larry Wall于1987年开发,Perl 5是Perl编程语言的第五个主要版本,于1994年发布。它是Perl编程语言的主要版本,并在很多方面得到广泛应用。

  1. 概述

  1. 新建正则表达式有两种方法。
  • 一种是使用字面量,以斜杠表示开始和结束。

var regex = /xyz/;

  • 另一种是使用RegExp构造函数。

var regex = new RegExp('xyz');

上面两种写法是等价的,都新建了一个内容为xyz的正则表达式对象。它们的主要区别是,第一种方法在引擎编译代码时,就会新建正则表达式,第二种方法在运行时新建正则表达式,所以前者的效率较高。而且,前者比较便利和直观,所以实际应用中,基本上都采用字面量定义正则表达式。

RegExp构造函数还可以接受第二个参数,表示修饰符。

var regex = new RegExp('xyz', 'i');

// 等价于

var regex = /xyz/i;

  1. 修饰符

  • i: 不区分大小写匹配。例如,/hello/i 可以匹配 "hello"、"Hello"、"HELLO" 等。
  • g: 全局匹配。如果正则表达式带有此修饰符,将会找到所有匹配项,而不是在找到第一个匹配项后停止。例如,/abc/g 可以匹配 "abcabcabc" 中的所有 "abc"。
  • m: 多行匹配。启用这个修饰符后,^ 和 $ 将匹配字符串的每一行的开头和结尾,而不仅仅是整个字符串的开头和结尾。
  • s: 单行匹配。启用这个修饰符后,. 将匹配包括换行符在内的任意字符。
  • u: 启用 Unicode 匹配。用于处理 Unicode 字符串,允许匹配 Unicode 字符。
  • y: 粘附匹配。它要求从目标字符串的特定位置开始匹配,从上一次匹配的结束位置继续。这在进行连续的匹配时很有用。

实列:

const text = "Hello, World! Hello, hello.";

const regex = /hello/gi; // 匹配所有的 "hello",不区分大小写

const matches = text.match(regex);

console.log(matches); // Output: [ 'Hello', 'hello', 'hello' ]:

1.实列属性

 

示列:

var r = /abc/igm;

r.ignoreCase // true

  1. 实例方法

 

  1. 示例
  1. RegExp.prototype.exec()

var s = '_x_x';

var r = /_(x)/;

r.exec(s) // ["_x", "x"]

如果正则表示式包含圆括号(即含有“组匹配”),则返回的数组会包括多个成员。第一个成员是整个匹配成功的结果,后面的成员就是圆括号对应的匹配成功的组。也就是说,第二个成员对应第一个括号,第三个成员对应第二个括号,以此类推。整个数组的length属性等于组匹配的数量再加1。

上面代码的exec()方法,返回一个数组。第一个成员是整个匹配的结果,第二个成员是圆括号匹配的结果。

  1. String.prototype.match()

var s = 'abba';

var r = /a/g;

s.match(r) // ["a", "a"]

r.exec(s) // ["a"]

  1. String.prototype.search()

'_x_x'.search(/x/) // 1

上面代码中,第一个匹配结果出现在字符串的1号位置。

  1. String.prototype.replace()

'aaa'.replace('a', 'b') // "baa"

'aaa'.replace(/a/, 'b') // "baa"

'aaa'.replace(/a/g, 'b') // "bbb"

replace方法的第二个参数可以使用美元符号$,用来指代所替换的内容。更详细请自行搜索

  1. String.prototype.split()
  • 正则分隔,去除多余的空格

'a,  b,c, d'.split(/, */)

// [ 'a', 'b', 'c', 'd' ]

  •  指定返回数组的最大成员

'a,  b,c, d'.split(/, */, 2)

[ 'a', 'b' ]

  1. 匹配规则

字面量字符和元字符
  1. 点字符(.)

点字符(.)匹配除回车(\r)、换行(\n) 、行分隔符(\u2028)和段分隔符(\u2029)以外的任意一个字符。注意,对于码点大于0xFFFF字符,点字符不能正确匹配,会认为这是两个字符。

/c.t/

上面代码中,c.t匹配c和t之间包含任意一个字符的情况

  1. 位置字符

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

  • ^ 表示字符串的开始位置
  • $ 表示字符串的结束位置

// test必须出现在开始位置

/^test/.test('test123') // true

// test必须出现在结束位置

/test$/.test('new test') // true

(3)选择符(|

竖线符号(|)在正则表达式中表示“或关系”(OR),即cat|dog表示匹配cat或dog。

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

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

/fred|barney|betty/

选择符会包括它前后的多个字符,比如/ab|cd/指的是匹配ab或者cd,而不是指匹配b或者c。如果想修改这个行为,可以使用圆括号。

/a( |\t)b/.test('a\tb') // true

上面代码指的是,a和b之间有一个空格或者一个制表符。

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

转义符

正则表达式中那些有特殊含义的元字符,如果要匹配它们本身,就需要在它们前面要加上反斜杠。比如要匹配+,就要写成\+。

正则表达式中,需要反斜杠转义的,一共有12个字符:^、.、[、$、(、)、|、*、+、?、{和\。需要特别注意的是,如果使用RegExp方法生成正则对象,转义需要使用两个斜杠,因为字符串内部会先转义一次。

特殊字符

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

  • \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)表示有一系列字符可供选择,只要匹配其中一个就可以了。所有可供选择的字符都放在方括号内,比如[xyz] 表示x、y、z之中任选一个匹配。

/[abc]/.test('hello world') // false

/[abc]/.test('apple') // true

上面代码中,字符串hello world不包含a、b、c这三个字母中的任一个,所以返回false;字符串apple包含字母a,所以返回true。

有两个字符在字符类中有特殊含义。

  1. 脱字符(^)

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

/[^abc]/.test('bbc news') // true

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

var s = 'Please yes\nmake my day!';

s.match(/yes.*day/) // null

s.match(/yes[^]*day/) // [ 'yes\nmake my day']

注意,脱字符只有在字符类的第一个位置才有特殊含义,否则就是字面含义。

  1. 连字符(-)

某些情况下,表示字符的连续范围。比如,[abc]可以写成[a-c],[0123456789]可以写成[0-9],同理[A-Z]表示26个大写字母。

当连字号不出现在方括号之中,就不具备简写的作用,只代表字面的含义

以下都是合法的字符类简写形式。

[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

上面代码中,\u0128-\uFFFF表示匹配码点在0128到FFFF之间的所有字符。

预定义模式

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

  • \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,m}表示重复不少于n次,不多于m次。

/lo{2}k/.test('look') // true

/lo{2,5}k/.test('looook') // true

上面代码中,第一个模式指定o连续出现2次,第二个模式指定o连续出现2次到5次之间。

量词符——?、*、+

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

  • ? 问号表示某个模式出现0次或1次,等同于{0, 1}。
  • * 星号表示某个模式出现0次或多次,等同于{0,}。
  • + 加号表示某个模式出现1次或多次,等同于{1,}。
贪婪模式——最大可能匹配

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

var s = 'aaa';

s.match(/a+/) // ["aaa"]

非贪婪模式,即最小可能匹配。只要一发现匹配,就返回结果,不要往下检查。如果想将贪婪模式改为非贪婪模式,可以在量词符后面加一个问号。

var s = 'aaa';

s.match(/a+?/) // ["a"]

上面例子中,模式结尾添加了一个问号/a+?/,这时就改为非贪婪模式,一旦条件满足,就不再往下匹配,+?表示只要发现一个a,就不再往下匹配了。

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

'abb'.match(/ab*/) // ["abb"]

'abb'.match(/ab*?/) // ["a"]

'abb'.match(/ab?/) // ["ab"]

'abb'.match(/ab??/) // ["a"]

上面例子中,/ab*/表示如果a后面有多个b,那么匹配尽可能多的b;/ab*?/表示匹配尽可能少的b,也就是0个b。

组匹配——()
  1. 概述

正则表达式的括号表示分组匹配,括号中的模式可以用来匹配分组的内容。

/fred+/.test('fredd') // true

/(fred)+/.test('fredfred') // true

上面代码中,第一个模式没有括号,结果+只表示重复字母d,第二个模式有括号,结果+就表示匹配fred这个词。

下面是另外一个分组捕获的例子。

var m = 'abcabc'.match(/(.)b(.)/);

m

// ['abc', 'a', 'c']

上面代码中,正则表达式/(.)b(.)/一共使用两个括号,第一个括号捕获a,第二个括号捕获c。

注意,使用组匹配时,不宜同时使用g修饰符,否则match方法不会捕获分组的内容。

  1. 非捕获组——(?:x)

(?:x)称为非捕获组(Non-capturing group),表示不返回该组匹配的内容,即匹配的结果中不计入这个括号。

请看下面的例子。

var m = 'abc'.match(/(?:.)b(.)/);

m // ["abc", "c"]

上面代码中的模式,一共使用了两个括号。其中第一个括号是非捕获组,所以最后返回的结果中没有第一个括号,只有第二个括号匹配的内容。

下面是用来分解网址的正则表达式。

// 正常匹配

var url = /(http|ftp):\/\/([^/\r\n]+)(\/[^\r\n]*)?/;

url.exec('http://google.com/');

// ["http://google.com/", "http", "google.com", "/"]

// 非捕获组匹配

var url = /(?:http|ftp):\/\/([^/\r\n]+)(\/[^\r\n]*)?/;

url.exec('http://google.com/');

// ["http://google.com/", "google.com", "/"]

上面的代码中,前一个正则表达式是正常匹配,第一个括号返回网络协议;后一个正则表达式是非捕获匹配,返回结果中不包括网络协议。

  1. 先行断言——x(?=y)

x(?=y)称为先行断言(Positive look-ahead),x只有在y前面才匹配,y不会被计入返回结果。

比如,要匹配后面跟着百分号的数字,可以写成/\d+(?=%)/。

“先行断言”中,括号里的部分是不会返回的。

var m = 'abc'.match(/b(?=c)/);

m // ["b"]

上面的代码使用了先行断言,b在c前面所以被匹配,但是括号对应的c不会被返回。

  1. 先行否定断言——x(?!y)

x(?!y)称为先行否定断言(Negative look-ahead),x只有不在y前面才匹配,y不会被计入返回结果

比如,要匹配后面跟的不是百分号的数字,就要写成/\d+(?!%)/。

/\d+(?!\.)/.exec('3.14')

// ["14"]

上面代码中,正则表达式指定,只有不在小数点前面的数字才会被匹配,因此返回的结果就是14。

“先行否定断言”中,括号里的部分是不会返回的。

var m = 'abd'.match(/b(?!c)/);

m // ['b']

上面的代码使用了先行否定断言,b不在c前面所以被匹配,而且括号对应的d不会被返回。

注意:利用正则表达式和编码方式可以实行多样操作

  • Javascript对象

概述

对象(object)是 JavaScript 语言的核心概念,也是最重要的数据类型。

什么是对象?简单说,对象就是一组“键值对”(key-value)的集合,是一种无序的复合数据集合。

var obj = {

  foo: 'Hello',};

上面代码中,大括号就定义了一个对象,它被赋值给变量obj,所以变量obj就指向一个对象。该对象内部包含两个键值对(又称为两个“成员”),第一个键值对是foo: 'Hello',其中foo是“键名”(成员的名称),字符串Hello是“键值”(成员的值)。

键名属性方法创建

  1. 对象的所有键名都是字符串(ES6 又引入了 Symbol 值也可以作为键名),所以加不加引号都可以。
  2. 如果键名不符合标识名的条件(比如第一个字符为数字,或者含有空格或运算符),且也不是数字,则必须加上引号,否则会报错。
  3. 对象的每一个键名又称为“属性”(property),它的“键值”可以是任何数据类型。如果一个属性的值为函数,通常把这个属性称为“方法”,它可以像函数那样调用。

var obj = {

  p: function (x) {

    return 2 * x;

  }

};

obj.p(1) // 2

如果属性的值还是一个对象,就形成了链式引用。

对象的属性之间用逗号分隔,最后一个属性后面可以加逗号,也可以不加。

  1. 属性可以动态创建,不必在对象声明时就指定。

var obj = {};

obj.foo = 123;

obj.foo // 123

上面代码中,直接对obj对象的foo属性赋值,结果就在运行时创建了foo属性。JavaScript 允许属性的“后绑定”,也就是说,你可以在任意时刻新增属性,没必要在定义对象的时候,就定义好属性。。

对象的引用

如果不同的变量名指向同一个对象,那么它们都是这个对象的引用,也就是说指向同一个内存地址。修改其中一个变量,会影响到其他所有变量。如果取消某一个变量对于原对象的引用,不会影响到另一个变量。

这种引用只局限于对象,如果两个变量指向同一个原始类型的值。那么,变量这时都是值的拷贝

var x = 1;

var y = x;

x = 2;

y // 1

上面的代码中,当x的值发生变化后,y的值并不变,这就表示y和x并不是指向同一个内存地址。

对象采用大括号表示,这导致了一个问题:如果行首是一个大括号,它到底是表达式还是语句?

{ foo: 123 }

JavaScript 引擎读到上面这行代码,会发现可能有两种含义。第一种可能是,这是一个表达式,表示一个包含foo属性的对象;第二种可能是,这是一个语句,表示一个代码区块,里面有一个标签foo,指向表达式123。

为了避免这种歧义,JavaScript 引擎的做法是,如果遇到这种情况,无法确定是对象还是代码块,一律解释为代码块。

{ console.log(123) } // 123

上面的语句是一个代码块,而且只有解释为代码块,才能执行。

如果要解释为对象,最好在大括号前加上圆括号。因为圆括号的里面,只能是表达式,所以确保大括号只能解释为对象。

这种差异在eval语句(作用是对字符串求值)中反映得最明显。

eval('{foo: 123}') // 123

eval('({foo: 123})') // {foo: 123}

上面代码中,如果没有圆括号,eval将其理解为一个代码块;加上圆括号以后,就理解成一个对象。

属性的操作

属性的读取赋值

  1. 读取对象的属性,有两种方法,一种是使用点运算符,还有一种是使用方括号运算符。

var obj = {  p: 'Hello World'};

obj.p // "Hello World"

obj['p'] // "Hello World"

上面代码分别采用点运算符和方括号运算符,读取属性p。

请注意,如果使用方括号运算符,键名必须放在引号里面,否则会被当作变量处理。

var foo = 'bar';

var obj = {

foo: 1,

bar: 2

};

obj.foo  // 1

obj[foo]  // 2

上面代码中,引用对象obj的foo属性时,如果使用点运算符,foo就是字符串;如果使用方括号运算符,但是不使用引号,那么foo就是一个变量,指向字符串bar。

  1. 方括号运算符内部还可以使用表达式。

obj['hello' + ' world']

obj[3 + 3]

数字键可以不加引号,因为会自动转成字符串。

注意,数值键名不能使用点运算符(因为会被当成小数点),只能使用方括号运

  1. 点运算符和方括号运算符,不仅可以用来读取值,还可以用来赋值。

var obj = {};

obj.foo = 'Hello';

obj['bar'] = 'World';

属性的查看删除

  1. 查看一个对象本身的所有属性,可以使用Object.keys方法。

var obj = {};

Object.keys(obj);

  1. delete命令用于删除对象的属性,删除成功后返回true。

var obj = { p: 1 };

Object.keys(obj) // ["p"]

delete obj.p // true

上面代码中,delete命令删除对象obj的p属性。

注意,删除一个不存在的属性,delete不报错,而且返回true。因此,不能根据delete命令的结果,认定某个属性是存在的。

另外,需要注意的是,delete命令只能删除对象本身的属性,无法删除继承的属性

var obj = {};

delete obj.toString // true

obj.toString // function toString() { [native code] }

上面代码中,toString是对象obj继承的属性,虽然delete命令返回true,但该属性并没有被删除,依然存在。这个例子还说明,即使delete返回true,该属性依然可能读取到值。

属性的遍历:for...in 循环

for...in循环用来遍历一个对象的全部属性。

var obj = {a: 1, b: 2, c: 3};

for (var i in obj) {

  console.log('键名:', i);

  console.log('键值:', obj[i]);

}

for...in循环有两个使用注意点。

  • 它遍历的是对象所有可遍历(enumerable)的属性,会跳过不可遍历的属性。
  • 它不仅遍历对象自身的属性,还遍历继承的属性。

举例来说,对象都继承了toString属性,但是for...in循环不会遍历到这个属性。

对象obj继承了toString属性,该属性不会被for...in循环遍历到,因为它默认是“不可遍历”的。关于对象属性的可遍历性,参见《标准库》章节中 Object 一章的介绍。

如果继承的属性是可遍历的,那么就会被for...in循环遍历到。但是,一般情况下,都是只想遍历对象自身的属性,所以使用for...in的时候,应该结合使用hasOwnProperty方法,在循环内部判断一下,某个属性是否为对象自身的属性。

with语句的格式如下:

with (对象) {

  语句;

}

它的作用是操作同一个对象的多个属性时,提供一些书写的方便。

with (document.links[0]){

  console.log(href);

  console.log(title);

  console.log(style);

}

// 等同于

console.log(document.links[0].href);

console.log(document.links[0].title);

console.log(document.links[0].style);

注意,如果with区块内部有变量的赋值操作,必须是当前对象已经存在的属性,否则会创造一个当前作用域的全局变量。

这是因为with区块没有改变作用域,它的内部依然是当前作用域。这造成了with语句的一个很大的弊病,就是绑定对象不明确。

with (obj) {

  console.log(x);

}

建议不要使用with语句,可以考虑用一个临时变量代替with。

with(obj1.obj2.obj3) {

  console.log(p1 + p2);

}

// 可以写成

var temp = obj1.obj2.obj3;

console.log(temp.p1 + temp.p2);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值