【JavaScript】欺骗JavaScript作用域:eval和with

1,eval()

eval(…) 函数可以接受一个字符串为参数,并将其中的内容视为好像在书写时就存在于程序中这个位置的代码。
看一个例子:

function foo(str, a) {
eval( str ); // 欺骗!
console.log( a, b );
}
var b = 2;
foo( "var b = 3;", 1 ); // 1, 3

eval(…) 调用中的 “var b = 3;” 这段代码会被当作本来就在那里一样来处理。由于那段代
码声明了一个新的变量 b ,因此它对已经存在的 foo(…) 的作用域进行了修改。因此会输出1, 3

2,with

with 通常被当作重复引用同一个对象中的多个属性的快捷方式,可以不需要重复引用对象
本身。
比如:

	var obj = {
		a: 1,
		b: 2,
		c: 3
	};
	// 单调乏味的重复 "obj"
	obj.a = 2;
	obj.b = 3;
	obj.c = 4;
	// 简单的快捷方式
	with (obj) {
		a = 3;
		b = 4;
		c = 5;
	}

再看一个例子:

function foo(obj) {
	with (obj) {
		a = 2;
	}
}
var o1 = {
	a: 3
};
var o2 = {
	b: 3
};
foo( o1 );
console.log( o1.a ); // 2
foo( o2 );
console.log( o2.a ); // undefined
console.log( a ); // 2  ,a 被泄漏到全局作用域上了

为什么执行foo( o2 ); 之后o2.a时undefined呢?
当 o2 传递进去, o2 并没有 a 属性,因此不会创建这个属性,o2.a 保持 undefined 。

可为什么a会在全局作用域中呢?
在执行with(o2)时,o2中并没有 a 标识符,然后会继续在foo()的作用域中寻找a,没找到的话就接着往下找,最后在全局作用域中都没有找到标识符 a,因此当 a=2 执行时,自动创建了一个全局变量

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值