你可能学了假的JavaScript!不信你来看!

《交个朋友,绝非潘嘎之交》


Adobe一个高级工程师 Dmitry Baranovskiy 在他的博客上写了这么一篇博文《So,you think you know JavaScript?》,并在博文中贴出了五个小示例,大家可以感受一下,看看你是不是学了假的JavaScript!

if (!("a" in window)) {
    var a = 1;
}
alert(a);
var a = 1,
    b = function a(x) {
        x && a(--x);
    };
alert(a);
function a(x) {
    return x * 2;
}
var a;
alert(a);
function b(x, y, a) {
    arguments[2] = 10;
    alert(a);
}
b(1, 2, 3);
function a() {
    alert(this);
}
a.call(null);

感受完了请先将你的答案写出来,然后再去实际测试一下……如果错了一两个说明你JavaScript基础不牢,如果错了三四个了,那就只能说明你学了假的JavaScript!


###博主学习总结
####示例1
#####示例1原型:

**分析:**首先会解析所有函数,其次是var声明的变量,但是不会赋值。因为javascript没有块的概念。像for(var i in array)这里的i依然是全局变量。
执行顺序:
1.var a;//声明一个变量,但是不会赋值
2.if语句,全局变量相当于window的属性,所以"a" in window为真,取反为假。故不会执行大括号里面的语句。
3.alert(a);//undefined

#####示例1变形:

if (("a" in window)) {
		var a = 1;
	}
	alert (a);
	

执行结果是1,可能有的童鞋会说,var a =1 是在if{}中定义的,属于局部变量呀,怎么能在外面取出来?别怀疑,真的会有人这么问,今天就有一个同事这么问了我……
Javascript变量的scope是根据方法块来划分的(也就是说以function的一对大括号{ }来划分)。切记,是function块,而for、while、if块并不是作用域的划分标准!
所以这里的a依然是全局变量。

####示例2
#####示例2原型:

分析: JavaScript中定义变量时,也可以同时定义多个,例如var a,b,c;在定义变量时使用函数表达式就类似于局部变量,不会被全局作用域中访问到。
执行顺序:
1.声明两个变量var a,b;并给他们赋值a=1,b=function a(){…};这里的function a是局部变量,外部无法访问到。因此全局a还是1.
2.alert(a);//1
#####示例2变形:
这样写的话大家比较一下可能更能理解一点

	var a = 1,
     b = function a (x) {
        x && a (--x);
	    alert(a);//打印看一下a是什么值,和外面打印的a进行比较
		return x;//返回一个值,这个值其实就是给b赋的值
    };
    alert (a);//这里只能取到全局变量a
	alert (a(1)); //报错: a is not a function
	alert(b);
	alert(b(1));

####示例3
#####示例3原型:

分析: js永远是先解析声明式函数,再解析变量。
执行顺序:
1.解析函数a;
2.声明变量var a;因为a此时没有被赋值,所以它还是指向原来的值。即function a;
3.alert(a);
#####示例3变形:
如果要证明js解析的顺序,很简单,把代码位置换一下:

	var a;
	function a (x) {
		return x * 2;
	}
	alert (a);

####示例4
#####示例4原型:

***分析:***在函数内部可以引用一个对象,它是arguments类似数组,但不是数组。它代表了函数实际接收参数的集合。可以通过下标对相应参数进行访问。如果修改此对象某些属性,如arguments[index],则被传进来的第index(如果有的话,下标从0开始)变量的值也会被修改。
执行顺序:
1.声明一个函数b;
2.执行函数b(1,2,3);因为这里arguments[2]与变量a引用的是一个值,所以当arguments[2]改变时,a也随之改变。

####示例5
#####示例5原型:

call方法:
语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明: call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。

分析
call方法接受多个参数,其作用是借用别人的方法当作自己的方法。这样能保证执行的时候this能够指向自己。call方法的第二个参数到最后一个参数是传给借用过来函数的。第一个参数是借用的对象,如果这个对象为空,那么将会作为全局window对象调用。即函数中的this指向window。

对call方法还不了解的可以去问问度娘或谷老师
推荐一篇不错的介绍:JavaScript中神奇的call()方法

以上五个示例测试的结果:
1:undefined
2:1
3: function a (x) {
return x * 2;
}

4:1、2、3、undefined、10
5:object Windows

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值