Javascript教程:关于深入了解JS的几个问题

2016-02-20 01:05 4 1 收藏

想不想get新技能酷炫一下,今天图老师小编就跟大家分享个简单的Javascript教程:关于深入了解JS的几个问题教程,一起来看看吧!超容易上手~

【 tulaoshi.com - Web开发 】

看了Dmitry Baranovskiy写的这篇,也拜读了,对Javascript的了解又进了一步,尝试把自己的理解记录如下
第一题:

DaimaRen.cn © 2009-2010 by Tomie Zhang
if (!("a" in window)) {var a = 1;}alert(a);

这一题是对JS变量的考察,这个测试翻译成自然语言大意是:如果window里不存在a这个属性,那么就定义个a的变量并给它赋值等于1。 这里本来期望的值是1,但是很可惜它会弹出undefined,这是为什么呢?首先javascript的全局变量都是window的属性(properties),你可以用形如:

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/webkaifa/)DaimaRen.cn © 2009-2010 by Tomie Zhang
alert("Daimaren.cn" in winodw)

来查看,var a = 1 等同于 window.a = 1,其次javascript引擎在扫描代码时是将变量提前到scope之前运行,如:

DaimaRen.cn © 2009-2010 by Tomie Zhang
alert("a" in window);var a;

其实在解析之后是

DaimaRen.cn © 2009-2010 by Tomie Zhang
var a;alert("a" in window);

所以它的结果是true,最后javascript的声明与初始化是分开的,

DaimaRen.cn © 2009-2010 by Tomie Zhang
var a = 1;/*其实在运行时将变为*/var a;a=1;

javascript会自动将这两个步骤分拆,Nicholas的解释是这种分拆可以让声明前置在scope上方,而为什么要这么做,是因为声明时就初始化变量,可能影响代码运行时变量的值,导致意外的结果。
so,知道了这些,那么开始那个测试其实在运行时会是这个样子:

DaimaRen.cn © 2009-2010 by Tomie Zhang
var a;//自动前置运行的变量,没有初始化if (!("a" in window)) {//FLASEvar a = 1;}alert(a);//弹出undefined

第二题:

DaimaRen.cn © 2009-2010 by Tomie Zhang
var a = 1,b = function a(x) {x && a(--x);};alert(a);

如果理解上第一题,那这个题就很好解决了,这是关于function的,它有2种,一种是函数声明(function declaration),一种是函数表达式(function expression),形如:

DaimaRen.cn © 2009-2010 by Tomie Zhang
function Daimaren(){//这是一个函数声明  do anything you want here........}var Daimaren = function(){//这是一个函数表达式  do anything you want here........}

所有的函数声明在运行时是会被前置运行的,而函数表达式则不会,运行如下两段代码:

DaimaRen.cn © 2009-2010 by Tomie Zhang
foo();//将会弹出什么呢?function foo(){alert("i am a function function declaration from daimaren.cn");}var foo = function(){alert("i am a function function expression from daimaren.cn");}
DaimaRen.cn © 2009-2010 by Tomie Zhang
function foo(){alert("i am a function function declaration from daimaren.cn");}var foo = function(){alert("i am a function function expression from daimaren.cn");}foo();//又将会弹出什么呢?

通过这两个例子我们可以请清楚的知道,第二题的答案将一直是1.
第三题

DaimaRen.cn © 2009-2010 by Tomie Zhang
function a(x) {return x * 2;}var a;alert(a);

如果理解了前面的变量前置的概念,那这个也很好理解了,唯一不同的是函数声明的优先级是高于普通的变量声明的除非变量声明被初始化,也就是说,上面这段代码将先去执行function a而忽略掉var a,考虑如下:

DaimaRen.cn © 2009-2010 by Tomie Zhang
function a(x) {return x * 2;}var a = 1;alert(a);

第四题

DaimaRen.cn © 2009-2010 by Tomie Zhang
function b(x, y, a) {arguments[2] = 10;alert(a);}b(1, 2, 3);

这个很好理解,运行的值为10,这里主要是对arguments的理解,引下ECMA-262第三版 10.1.8章节对arguments的解释如下:

For each non-negative integer, arg, less than the value of the length property, a property is created with name ToString(arg) and property attributes { DontEnum }. The initial value of this property is the value of the corresponding actual parameter supplied by the caller. The first actual parameter value corresponds to arg = 0, the second to arg = 1, and so on. In the case when arg is less than the number of formal parameters for the Function object, this property shares its value with the corresponding property of the activation object. This means that changing this property changes the corresponding property of the activation object and vice versa.

参数对象相当于对应参数建立的副本,参数改变它也会跟着改变,他们的对应关系,例如在上面这个函数里arguments[0]对应x,arguments[1]对应y,arguments[2]对应a,看起来似乎是array但是当你typof的时候会发现他们是object对象。对他们的对应关系理解如下例:

DaimaRen.cn © 2009-2010 by Tomie Zhang
function b(x, y, a) {arguments[2] = x;alert(a);//期望是3?但是看上一句,已经被指向了x,所以是1}b(1,2,3);

第五题

DaimaRen.cn © 2009-2010 by Tomie Zhang
function a() {alert(this);}a.call(null);

这个是call了(我比较头疼的东西,囧,可是大师却说是这5道题目里最简单的),来看下。首先,要搞清楚this指针是指向什么的,Nicholas举的例子:

DaimaRen.cn © 2009-2010 by Tomie Zhang
var o= {method: function() {alert(this === o);//true}}o.method();

在method被呼叫的时候,tihs指向了o,因为它是o下的一个方法,它的上下文是在o中的,而如果它不在o这个object中,那么它将会指向window:

DaimaRen.cn © 2009-2010 by Tomie Zhang
function method() {alert(this === window);//true}o.method();

OK,那接下来要知道call是干什么的,话说call是一个比较奇妙的方法,也很容易让人迷糊,官方的解释:

call 方法
请参阅
应用于:Function 对象
要求
版本 5.5
调用一个对象的一个方法,以另一个对象替换当前对象。

call([thisObj[,arg1[, arg2[, [,.argN]]]]])
参数
thisObj
可选项。将被用作当前对象的对象。
arg1, arg2, , argN
可选项。将被传递方法参数序列。
说明
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。

如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。

官方解释很容易让人迷糊,Nicholas大湿的解释如下:

The call() method executes a function as if it were a method of another object

那不如看个例子吧:

DaimaRen.cn © 2009-2010 by Tomie Zhang
function add(a,b){alert(a+b);}function sub(a,b){alert(a-b);} add.call(sub,3,1); //4

这里其实就是用add的方法替换了sub的方法并且把参数值传进去,等同于

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/webkaifa/)DaimaRen.cn © 2009-2010 by Tomie Zhang
add.call(sub,3,1) == add(3,1)

好了,理解了this指针以及call,那回头看这个题目,那它其实就相当于:

DaimaRen.cn © 2009-2010 by Tomie Zhang
function a() {alert(this);}a(null);

this不受任何影响指向的是a这个函数声明,而a这个函数声明则是一个object,于是结果就很明显啦。
这算是半翻译加半自己的理解,如有错误还请指教. 另外Nicholas大师说有的人就喜欢拿这样的题目当面试题,他觉得不尊重面试者也没什么用处,因为以上这些错误或者点不是平常工作都能遇到的,就如同面试乘务员而让人家去解释喷气式动力的原理一样这个很赞同,学术研究下即可,如果拿去故意刁难人就有点不太好了。

来源:http://www.tulaoshi.com/n/20160220/1633227.html

延伸阅读
带你深入了解摄影曝光量   曝光量 第一节:控制曝光量 什么是曝光量 定义:感光器在曝光时间内接收到光的多少。 根据这一定义可知: 曝光量=感光器接收光的速度×曝光时间 而感光器接收光的速度=环境光的强度×光圈 感光器接收光的速度示意图: 曝光时间就是快门开启的时间...
标签: 营养价值
有相当一部分的人到现在一直不知道千页豆腐是什么,其实千页豆腐看起来和豆腐差不多,但口感一吃就吃出来哪个是千叶豆腐,哪个就是豆腐。想知道千页豆腐的做法大全以及千页豆腐的营养价值吗?那就一起来看看吧。 千页豆腐的营养价值虽然没有豆腐那么高,但也不低,所以适当吃些还是很好的,下面就给你们介绍下千页豆腐到底是什么。 ...
这两个都是经常被问的问题 一个是关于入门书籍的选择, 一个是关于内存管理 谈谈我的体会 kenshinji 写到: 呵呵。。。。偶想买一本好一点的linux的入门级的书。现在偶只有电脑里down下来的电子版的。。。。看着不爽你能给我推荐一本么?我在长沙。。。。发现市面上电脑的书还是以“瘟到死”的居多。偶一直觉得O'RAILLY出的书不错。。。呵呵另外...
首先,Oracle的字典表和视图基本上可以分为三个层次。 1.1 X$表 这一部分表是Oracle数据库的运行基础,在数据库启动时由Oracle应用程序动态创建。 这部分表对数据库来说至关重要,所以Oracle不允许SYSDBA之外的用户直接访问,显示授权不被允许。 如果显示授权你会收到如下错误: SQL grant select on x$ksppi to eygle; ...
       关于Linux下编写和编译程序的几个问题   · 闫健勇·CPCW       当前,虽然Linux还不很普及,在Linux下编写和编译程序的人不多。但是我相信,随着Linux性能的不断提升和逐渐普及,会有许多自由软件出现,也会有许多人成为Linux下的程序员。我结合自己的经验,介绍一...

经验教程

22

收藏

94
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部