看了汤姆大叔的“你真懂JavaScript吗?”,里面有5道题目,我都一一作了,然后在chrome的控制台里面运行了一遍,虽然只错了一道,但还是细细读了下答案,在此总结一下,看看是否对大家对这些JavaScript底层的原理都懂了。

题目一(所有全局变量都是window的属性、变量声明提前、变量赋值不会提前)

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

因为在JavaScript在变量声明提前的特性,所以事实上上述代码相当于下面所示:

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

因为所有的全局变量都是window的属性,所以不会进入循环体内也就不会执行a=1 这也就是为什么答案是undefined

题目二(函数声明提前、函数表达式相当于变量赋值所以不会提前、函数声明会覆盖变量声明,但不会覆盖变量赋值)

var a = 1,
b = function a(x) {
x && a(--x);
};
alert(a);

这个题目的答案是1。事实上上述代码的相当于下而的代码

var a = 1,
b = function(x) {
x && b(--x);
};
alert(a);

原题目第二行代码中,b和a同时指向一个地方也就是函数的入口,但是a和b唯一不同的地方在于函数定义结束也就是};后,a就引用不到了,也就是说a的作用域只在函数体内,而b的作用域却在整个全局范围内。看图说话

这里面还有一个重要的概念就是:函数声明会覆盖变量声明,但不会覆盖变量赋值。看下面的例子:

function value(){
return 1;
}
var value;
alert(typeof value); //"function"

尽快变量声明在下面定义,但是变量value依然是function,也就是说这种情况下,函数声明的优先级高于变量声明的优先级,但如果该变量value赋值了,那结果就完全不一样了:

function value(){
return 1;
}
var value = 1;
alert(typeof value); //"number"

题目三(遇到同名的函数声明,函数变量不会重新定义)

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

相信你看懂了题目二的注释之后,这题肯定会了,把答案贴一下。

题目四(callee和caller及函数参数的一些关系)

function b(x, y, a) {
arguments[2] = 10;
alert(a);
}
b(1, 2, 3);//结果是

其实arguments跟数组类似,可以通过方括号语法访问它的每一个元素,另外arguments和命名参数可以一起使用,它们是共享的,但是这个共享其实不是真正的共享一个内存地址,而是2个不同的内存地址,使用JavaScript引擎来保证2个值是随时一样的,所以修改了arguments的值同时也会体现在命名参数上,当然这也有一个前提,那就是这个索引值要小于你传入的参数个数,也就是说如果你只传入2个参数,而还继续使用arguments[2]赋值的话,就会不一致,看如下代码:

function b(x, y, a) {
arguments[2] = 10;
alert(a);
}
b(1, 2);//这时候因为没传递第三个参数a,所以赋值10以后,alert(a)的结果依然是undefined,而不是10,但如下代码弹出的结果依然是10,因为和a没有关系。
function b(x, y, a) {
arguments[2] = 10;
alert(arguments[2]);
}
b(1, 2);//结果依然是10

不过在严格模式下是不允许修改arguments的值

严格模式对如何使用 arguments 对象做出了一些限制。首先,像前面例子中

arguments[2] = 10;

的赋值会变得无效。也就是说,即使把 arguments[2]设置为 10,y 的值仍然不会变成10。其次,重写 arguments 的值会导致语法错误(代码将不会执行)。

题目五(this的相关概念)

function a() {
alert(this);
}
a.call(null);

this说直白一点就是当前调用的对象,也就是说如果方法是某个对象的属性的话,那在该方法内的this就指向这个对象,this指向的是运行时的当前对象。如果某方法是全局函数的话,那该方法内的this就指向window

call方法主要是用来改变作用域链的,call方法作为一个function执行代表该方法可以让另外一个对象作为调用者来调用,call方法的第一个参数是对象调用者,随后的其它参数是要传给调用method的参数(如果声明了的话),根据ECMAScript262规范规定:如果第一个参数传入的对象调用者是null或者undefined的话,call方法将把全局对象(也就是window)作为this的值。所以,不管你什么时候传入null,其this都是全局对象window。

所以这题目的答案是[object Window]

看了汤姆大叔的“你真懂JavaScript吗?”的一些感慨的更多相关文章

  1. 真懂JavaScript吗

    你真懂JavaScript http://www.cnblogs.com/elegance/p/4195593.html 看了汤姆大叔的“你真懂JavaScript吗?”,里面有5道题目,我都一一作了 ...

  2. 你必须知道ASP.NET知识------关于动态注册httpmodule(对不起汤姆大叔)

    一.关于动态注册的问题 很多人看过汤姆大叔的MVC之前的那点事儿系列(6):动态注册HttpModule ,其实汤姆大叔没有发现httpmodule动态注册的根本机制在哪里. 亦即:怎么动态注册?为什 ...

  3. 汤姆大叔 javascript 系列 第20课 最后的5到javascript题目

    博客链接:http://www.cnblogs.com/TomXu/archive/2012/02/10/2342098.html 原题: 大叔注:这些题目也是来自出这5个题目的人,当然如果你能答对4 ...

  4. 我读汤姆大叔的深入理解js(二)

    继续汤姆大叔的js之旅. 揭秘命名函数表达式 函数表达式和函数声明 汤姆大叔在博客中引用ECMA规范:函数声明必须带有标识符,函数表达式可以省略.对于我来说这些概念的东西真是不所适从.还是大叔的实例带 ...

  5. 我读汤姆大叔的深入理解js(一)

    前言 闲来看看javascript,在圆子里发现了汤姆大叔的文章,先是整体瞄了几眼,感觉不错,然后细细研读.记录下自己的学习历程和个人理解.更重要的是作为笔记 高质量JS代码 在看汤姆大叔的这一系列文 ...

  6. 汤姆大叔的6道javascript编程题题解

    看汤姆大叔的博文,其中有篇(猛戳这里)的最后有6道编程题,于是我也试试,大家都可以先试试. 1.找出数字数组中最大的元素(使用Math.max函数) var a = [1, 2, 3, 6, 5, 4 ...

  7. 汤姆大叔的6道js题目

    汤姆大叔的6道javascript编程题题解 看汤姆大叔的博文,其中有篇(猛戳这里)的最后有6道编程题,于是我也试试,大家都可以先试试. 1.找出数字数组中最大的元素(使用Math.max函数) 1 ...

  8. [转载]深入理解JavaScript系列 --汤姆大叔

    深入理解JavaScript系列文章,包括了原创,翻译,转载,整理等各类型文章,如果对你有用,请推荐支持一把,给大叔写作的动力. 深入理解JavaScript系列(1):编写高质量JavaScript ...

  9. 深入理解JavaScript系列(转自汤姆大叔)

    深入理解JavaScript系列文章,包括了原创,翻译,转载,整理等各类型文章,如果对你有用,请推荐支持一把,给大叔写作的动力. 深入理解JavaScript系列(1):编写高质量JavaScript ...

随机推荐

  1. java并发:同步容器&并发容器

    第一节 同步容器.并发容器 1.简述同步容器与并发容器 在Java并发编程中,经常听到同步容器.并发容器之说,那什么是同步容器与并发容器呢?同步容器可以简单地理解为通过synchronized来实现同 ...

  2. ul、li实现横向导航按钮

    好久没写博客了,主要是懒得呼气都不想呼,上周分给我一个新的任务,就是自己新建一个系统,快速极限开发,虽然之前自己也做过小的系统,但毕竟是自己做,随着自己的心意做,没有做其他的限制等,现在呢是给公司做, ...

  3. [C#解惑] #1 在构造函数内调用虚方法

    谜题 在C#中,用virtual关键字修饰的方法(属性.事件)称为虚方法(属性.事件),表示该方法可以由派生类重写(override).虚方法是.NET中的重要概念,可以说在某种程度上,虚方法使得多态 ...

  4. Bootstrap中glyphicons-halflings-regular.woff字体报404错notfound

    今天查看网站的源代码,发现有个glyphicons-halflings-regular.woff文件没有找到,因为我的网站使用了bootstrap的Glyphicons 字体图标,因此需要加载Glyp ...

  5. linux | 管道符、输出重定向

    1 输出重定向 ll > a.txt 将 ll的结果写入到a.txt 2 管道符 ls -la | grep h* 这条命令的理解为:ls -la 的结果作为gerp h* 的结果 gerp 是 ...

  6. android 资讯阅读器

    最近找申请到了一个不错的接口 , 非常适合拿来写一个资讯类的app. 现在着手写,随写随更.也算是抛砖引玉.烂尾请勿喷.╭(╯^╰)╮ android 资讯阅读器 第一阶段目标样式(滑动切换标签 , ...

  7. 转 漫谈linux文件IO

    在Linux 开发中,有几个关系到性能的东西,技术人员非常关注:进程,CPU,MEM,网络IO,磁盘IO.本篇文件打算详细全面,深入浅出.剖析文件IO的细节.从多个角度探索如何提高IO性能.本文尽量用 ...

  8. 【51NOD 1478】括号序列的最长合法子段

    很恶心啊,一道水题改了半天,主要是各种细节没有注意到,包括左括号剩余时有可能会出错的情况,需要从后往前扫 贡献一组测试数据: ((()))())(())(( 答案:8 1 #include<cs ...

  9. 素数筛 uva 543

    给你一个n求出n由2个奇质因子的和  这2个因子差最大 没有就输出'Goldbach's conjecture is wrong. #include<stdio.h> #include&l ...

  10. Http 和TCP的关系,TCP长连接和短连接有什么区别?

    HTTP 协议即超文本传送协议(Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种应用.由于HTTP在 ...