JavaScript奥秘之让人捉摸不定的this
前言
之所以会有此篇文章当然还要从最近的一次面试说起,很抱歉居然又扯到面试上去看,其实不要说,平时不注意的东西,往往在面试时便会立马给你揪出来哪里有问题。
比如我当时就小小的栽了个跟头,栽跟头不要紧,要紧的是我确实对js的一些问题没有了解透彻。
俗话说的好,半灌水响叮当,我就那种一直认为自己js功底好的人,但真的拿出手来说,其实真的有点水了......此时再不好好学习一番,岂不是坐井观天,所以让我们开动吧!
小弟最近的文章基本都是边写边发,若是各位发现什么问题,或者感觉废话太多,请包涵。
闲扯作用域
你了解javascript的作用域吗?真的了解吗?那来试试这道题吧:
if (!("a" in window)) { var a = 1; } alert(a); 好吧,拿出你的答案吧,吾已经露出了易做图的笑容了,因为多数人看着这道题脑壳就有点昏(我会说我也有点昏吗???)
让我们一起来剥离她性感的外衣吧:
第一步:"a" in window这是什么意思?
意思是a是window的属性吗?那我们来做个试验:
我那个去,你会发现不管注释var a 还是不注释,a都是window的属性......于是上面答案呼之欲出!!!但我一团浆糊在我们脑袋中膨胀扩散......
在js的变量作用域中有个原则:所有变量声明都在范围作用域的顶部!
所以,之前我犯了一个愚蠢的错误,错的连我也吃惊,所以我把我自己喝大家都忽悠了,注意陷阱:
其实刚刚上面的完整代码是这样的:
<script type="text/javascript"> var a; var in_window = 'a' in window; alert(in_window); if (!("a" in window)) { var a = 1; } alert(a); </script> 这样的话:in_window自然是true,这才是隐藏的易做图!!!
若是注释下面这些代码的话:
终于正确了,刚刚因为自己的一个错误差点颠覆我最近学习的东西,太可怕了!
现在我们来看看“所有变量申明都会在范围作用域的顶部”是什么意思。
意思是在最下面定义的变量会自动提到上面去啦!!!所以我们定义变量时不如直接全部定义上去算啦。
回到本题:
if (!("a" in window)) { var a = 1; } alert(a); 其实他该是这个样子的。。。。
var a; if (!("a" in window)) { a = 1; } alert(a); 他将if里面的申明也提前了,怎么样不服气吧,其实我也是有点不服气,我想再试试:
var s = ''; if (false) { var a = 1; } 请注意,其中s没有任何意义,就是为了我方便设置断点:
至此易做图出现,无论如何a的申明都会提前包括以下几种情况:
var s = '';while (false) { var a = 1;} 变形一
学而不思则罔,我们将题目做个简单变形看看:
if (!("a" in window)) { a = 1; } alert(a); 在if里面去掉了申明,这道题就该是“1”了,但是若是if里面的代码不被执行的话就会报错了哟;
变形2:碰上了函数
刚刚那个现在看来就相对简单了,现在我们看看如此如此这般这般又会如何(我承认我闲的蛋疼好了)?
if (!("a" in window)) { var a = function () { window.a = 1; } } alert(a); 这样一改真的很蛋疼啦,这里不管a被定义为什么,但他是函数表达式,函数表达式就和原来一样,所以不变,if里面不会被执行!
那若是这个样子呢?
if (!("a" in window)) { function a() { window.a = 1; } } alert(a); 这个场景其实我也傻了,那么设置个断点看看:
看来a并不在window中,所以会执行if中的代码;
这里却又引出了另一个问题:到底变量提前或者函数提前?
var a = '1'; function a(){} alert(a); function a() { } var a = '1'; alert(a); 这两种写易做图导致最后输出有所不同吗???
答案是不会,他们的的结果都是1,原因就是函数式申明更加被优先啦,所以无论怎么写函数式什么都在最前面!!
function a() {return false; } if (a()) { var a = '1'; } s = ''; alert(a); function a() {return true; } if (a()) { var a = '1'; } s = ''; alert(a); 我们前面说过,无论如何,if里面的申明会提前,那么我们这两道题可以改写一下
var a = function () { return true }; var a; if (a()) { a = '1'; } s = ''; alert(a);
注意来:这里的10行,虽说申明了变量a却没有给其赋值,所以a还是函数,这从这里也可以看出来:
补充:web前端 , JavaScript ,