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

看了Dmitry Baranovskiy写的这篇So, you think you know JavaScript?,也拜读了Nicholas C. Zakas的答复,对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),你可以用形如:

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)) {//FLASE
    var 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的方法并且把参数值传进去,等同于

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大师说有的人就喜欢拿这样的题目当面试题,他觉得不尊重面试者也没什么用处,因为以上这些错误或者点不是平常工作都能遇到的,就如同面试乘务员而让人家去解释喷气式动力的原理一样…这个很赞同,学术研究下即可,如果拿去故意刁难人就有点不太好了。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索2010
, 函数
, 变量
, function
, 2009
, alert
, 关于arguments
前置声明
,以便于您获取更多的相关知识。

时间: 2024-08-29 05:31:33

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

ExtJS 4.2 教程-02:bootstrap.js 工作方式

转载自起飞网,原文地址:http://www.qeefee.com/extjs-course-2-bootstrap-js ExtJS 4.2 教程-01:Hello ExtJS ExtJS 4.2 教程-02:bootstrap.js 工作方式 ExtJS 4.2 教程-03:使用Ext.define自定义类 ExtJS 4.2 教程-04:数据模型 ExtJS 4.2 教程-05:客户端代理(proxy) ExtJS 4.2 教程-06:服务器代理(proxy) ExtJS 4.2 教程-0

JavaScript教程--从入门到精通(6)

javascript|教程 JavaScript对象系统的使用  使用浏览器的内部对象系统, 可实现与HTML文档进行交互.它的作用是将相关元素组织包装起来,提供给程序设计人员使用,从而减轻编程人的劳动,提高设计Web页面的能力. 一.浏览器对象层次及其主要作用 除了前面提到过的文档document对象外,Navigator浏览器中还提供了窗口(Window)对象以及历史(History)和位置(Location)对象. 浏览器对象(Navigator) 提供有关浏览器的信息 窗口对象(Wind

JavaScript教程--从入门到精通(5)

javascript|教程 在JavaScript中创建新对象   使用JavaScript可以创建自己的对象.虽然JavaScript内部和浏览器本身的功能已十分强大,但JavaScript还是提供了创建一个新对象的方法.使其不必像超文本标识语言那样,求于或其它多媒体工具,就能完成许多复杂的工作. 在JavaScript中创建一个新的对象是十分简单的.首先它必须定义一个对象,而后再为该对象创建一个实例.这个实例就是一个新对象,它具有对象定义中的基本特征. 一.对象的定义JavaScript对象

JavaScript教程--从入门到精通(4)

javascript|教程 基于对象的JavaScript语言 JavaScript语言是基于对象的(Object-Based),而不是面向对象的(object-oriented).之所以说它是一门基于对象的语言,主要是因为它没有提供象抽象.继承.重载等有关面向对象语言的许多功能.而是把其它语言所创建的复杂对象统一起来,从而形成一个非常强大的对象系统. 虽然JavaScript语言是一门基于对象的,但它还是具有一些面向对象的基本特征.它可以根据需要创建自己的对象,从而进一步扩大JavaScrip

JavaScript教程--从入门到精通(3)

javascript|教程 JavaScript程序构成 JavaScript脚本语言的基本构成是由控制语句.函数.对象.方法.属性等,来实现编程的. 一.程序控制流 在任何一种语言中,程序控制流是必须的,它能使得整个程序减小混乱,使之顺利按其一定的方式执行.下面是JavaScript常用的程序控制流结构及语句:1.if条件语句 基本格式if(表述式)语句段1:......else语句段2:..... 功能:若表达式为true,则执行语句段1:否则执行语句段2. 说明:if -else 语句是J

JavaScript教程--从入门到精通(2)

javascript|教程 JavaScript基本数据结构  JavaScript提供脚本语言的编程与C++非常相似,它只是去掉了C语言中有关指针等容易产生的错误,并提供了功能强大的类库.对于已经具备C++或C语言的人来说,学习JavaScript脚本语言是一件非常轻松愉快的事. 一.JavaScript代码的加入 JavaScript的脚本包括在HTML中,它成为HTML文档的一部分.与HTML标识相结合,构成了一个功能强大的Internet网上编程语言.可以直接将JavaScript脚本加

JavaScript教程--从入门到精通(1)

javascript|教程 JavaScript是由Netscape公司开发并随Navigator导航者一起发布的.介于Java与HTML之间.基于对象事件驱动的编程语言,正日益受到全球的关注.因它的开发环境简单,不需要Java编译器,而是直接运行在Web浏览器中,而因倍受Web设计者的所爱. 这一套JavaScript教程分九个章节从什么是JavaScript.JavaScript的简单应用一直介绍到如何用JavaScript实现复杂的交互,对于JavaScript初学者和进阶者来说,都是一部

JavaScript教程--从入门到精通(9)

javascript|教程 用JavaScript实现更复杂的交互 一.什么是框架 框架Frames最主要功用是"分割"视窗,使每个"小视窗"能显示不同的HTM L文件,不同框架之间可以互动(interact),这就是说不同框架之间可以交换讯息与资料.例如:假设您开了两个frames,第一个frame可显示书的目录,第二个frame则显示章节的具体内容. 框架可以将屏幕分割成不同的区域,每个区域有自己的URL,通过Frames[]数组对象来实现不同框架的访问.实际上

JavaScript教程--从入门到精通(8)

javascript|教程 用JavaScript脚本实现Web页面信息交互 要实现动态交互,必须掌握有关窗体对象(Form)和框架对象(Frames)更为复杂的知识. 一.窗体基础知识 窗体对象可以使设计人员能用窗体中不同的元素与客户机用户相交互,而用不着在之前首先进行数据输入,就可以实现动态改变Web文档的行为. 1.什么是窗体对象窗体(Form):它构成了Web页面的基本元素.通常一个Web页面有一个窗体或几个窗体,使用Forms[]数组来实现不同窗体的访问.<form Name=Form