javascript忍者秘籍pdf文字版免费下载
javascript忍者秘籍pdf文字版免费下载,javascript忍者秘籍(Secrets of the JavaScript Ninja 中文版)又叫JavaScript 忍者禁术, 在javascript忍者秘籍这本书中,到处都是一些有趣的技术和代码示例,目的
javascript忍者秘籍pdf文字版免费下载,javascript忍者秘籍(Secrets of the JavaScript Ninja 中文版) 又叫JavaScript 忍者禁术,
在javascript忍者秘籍这本书中,到处都是一些有趣的技术和代码示例,目的是想通过这些技
术和示例让你体会到其背后的思想和理念。
那些世界级的类库,正是基于这些思想构建和理念构建而成。
它们是:
·Prototype():2005 年由现代 JavaScript 库教父
SamStephenson 创建并发布的。封装了 DOM,Ajax 和 event 事件功
能,此外还有涉及到面向对象编程技术、面向方面编程技术和函数式编
程技术。
·jQuery():2006 年 1 月由 John Resig 发布,通过
CSS选择器来匹配DOM这种技术也因此库而流行起来。还包括:DOM,
Ajax,event,等灵活的功能。
现在,这两个库统治者 JavaScript 类库市场,被无数 web 站点和个人
使用。
下面是节选自javascript忍者秘籍书中的一段,完整版请下载javascript忍者秘籍pdf文字版。
我们都调用过 JavaScript 的函数,但是你是否停下来想一想,函数究竟
是如何被调用的。
在本章节中我们会解释一下几种不同的函数调用方式。
不同的函数调用方式,会产生非常不同的影响。其中最重要的一个影响,
就是 this 这个参数的定义。
这点不同比你想象要大的多,我们会在接下来的章节中讨论它,这个概
念也会伴随着本书余下的内容,
深刻的理解这个概念会让我们写出忍者级别的代码来。
这里列出了四种函数调用方式,他们之间拥有细微的不同:
他们是:
1.作为函数,在这里函数被调用,以一种很直接,易懂的方式。
2.作为方法,方法是连接在对象上面的,被这个对象调用,这中形
式就是面向对象编程。
3.作为构造器,在构造的过程中一个新的对象被创建出来。
4.经由函数的 apply()或 call()方法,这是一般比较复杂的概念,所
以我们稍后在用到的时候再来讨论。
方法,这是一般比较复杂的概念,所以我们稍后在用到的时候再来讨论。
但是我们最后忘记了一点,函数表达式的最后都会有一个圆括号,它表
示了这个函数被调用。
任何在圆括号中传入的变量,都会被翻译成一个列表,作为函数参数来
使用。
在我们开始讨论上面那四种函数调用模式之前,我们先来详细的讨论下
在函数被调用时候,参数是如何工作的。
3.3.1 变 量 称 为 参 数 (From arguments to function parameters)调用函数时候传入多个变量,每个变量都会赋值到此函数定义的时候的
参数。
例如第一个变量会成称为第一个参数,第二个变量会成为第二个参数,
以此类推。
如果传入的变量和函数定义的变量的个数不同的时候并不会报错;
JavaScript 在处理这个问题上很优雅,处理的具体细节如下:
· 如果调用时候传入的参数数目多于函数定义的变量个数,多出来的变
量不会赋值到函数定义时候的有名字的参数上。但我们仍然有方法获取
到这些多出来的变量。
· 如果函数定义的参数数目多于传入的变量,多出来的变量则会是
undefined。
非常有趣的一个地方是每个函数在被调用的时候,隐性的传入两个参数:
arguments 和 this
隐性的意思是,这两个参数不会在函数定义的时候出现,但是他们会在
函数被调用的时候悄悄的传入函数,并且作用域函数的作用域中。
不过他们可以被直接引用,就像其他显性定义的函数参数一样。
下面让我们来讨论一下这两个隐性的参数。
1.THE ARGUMENTS PARAMETER
argments 参数,即函数调用的时候传入函数的变量集合。
这个集合具有 length 属性,表示集合内变量的个数。
并且集合中的变量可以根据下标索引被引用。
argments 看起来很像 JavaScript 中的 Array,但是它并不是 Array。
尽管他们有共同的特征,例如 length 属性,可以通过下标索引到集合中
的变量,可以通过 for 语句来进行遍历。
但是你要是用其他 Array 中的方法来调用 argments,就会报错了。
所以 argments 只是"array-like"
相比起 argments,this 这个参数更有意思。
2.THE THIS PARAMETER当一个函数被调用的时候,我们可以看到变量赋到了显性的参数上,但
同时,一个叫做 this 的隐性参数也会传递到函数中。
参数 this 关联到一个对象,这个对象隐性的与函数的调用发生关系,我
们叫做函数上下文(function context)
函数上下文的概念来自于面向对象的语言,例如 java 中的 this 指向的
是一个类的实例,在类上会定义方法。
但是要注意,这里的方法调用只是我们之前提到的四种调用模式的其中
一种。
话说回来,JavaScript 的 this 指向什么,和 java 中的模式是不同的,
并不根据函数的定义,而是根据函数是如何被调用的,也就是根据函数
的调用模式的不同,this 的指向也不同。
根据这个事实,我们可以换种更清晰的称呼,我们就将 this 叫做调用的
上下文(invocation context),当然我们没有经过官方的协商来给 this 换
个称呼。
我们下面将要来看看之前说的四种函数调用模式的不同之处,我们会发
现其中最终要的一个不同之处就是在调用时候 this 指向的不同。我们会
利用很长的篇幅来继续讨论这个话题。所以不要担心你现在没有理解这
个问题。
现在让我们来看看函数是如何被调用的。
3.3.2 函数调用模式(Invocation as a function)“作为一个函数来调用",从字面来看好像没啥意义,函数当然是作为函
数来调用,除了函数还能有什么其他的吗?
其实,我们说一个函数的调用模式是作为一个函数来调用,是要与其它
三种调用模式做区分。
其他的三种调用模式为:方法调用模式,构造器调用模式,apply/call
调用模式。
当一个函数的调用方式不是这三种之一的时候,我们就将这个调用模式
叫做函数调用模式。
这种调用模式的触发是由于函数后面加上()操作符,并且这个函数并不
属于任何一个对象的一个属性(如果是属于对象的一个属性,那么这个
模式就成为了方法调用模式,我们下面会讨论)。
简单的实例如下: function ninja(){}; ninja();
var samurai = function(){}; samurai();
当我们用这种模式来调用函数的时候,函数的上下文(function context)
是全局的上下文(global context),
即 window 对象。
我们先不用代码来说明这个问题,在下面讨论方法调用模式的时候,我
们再来写一些有比较的代码。
3.3.3 方法调用模式(Invocation as a method)一个函数是一个对象的属性,当这个函数被调用时候,这个函数就视为
这个对象的一个方法,例如: var o = {}; o.whatever = function(){}; o.whatever();
OK,so what?这个函数就叫做“方法”(method),但是,这有啥意义吗?
如果你是来着与面向对象编程的开发人员,你应该记得,方法中的 this
就是这个方法所属的对象。
在这个例子中,也是这么回事。
当这个函数作为一个对象的方法被调用的时候,这个对象就成为了这个
函数的上下文(function context),
并且通过 this 函数作为载体存在于函数之中。
这就是最重要的意义之一。
JavaScript 允许面向对象编程的存在(构造器是另外一个,我们稍后讨
论)
让我们看几个例子,来对比一下函数调用模式和方法调用模式的不同:
Listing 3.3 Illustrating the difference between function and method invocations
function creep(){ return this; }
assert(creep() == window, "Creeping in the window");
var sneak = creep;
assert(sneak() == window, "Sneaking in the window");
var ninja1 = { skulk: creep };
assert(ninja1.skulk() === ninjal, "The 1st ninja is skulking");
var ninja2 = { skulk: creep };
assert(ninja2.skulk() === ninja2, "The 2nd ninja is skulking");
运行后,我们得出结论:
函数式的调用模式的 this 为 window
方法式的调用模式为方法所属的对象。
这里值得注意的一个地方,ninja1 和 ninja2 的 skulk 属性引用的是同一
个函数 creep
但是当 creep 执行的时候,产生的 this 却是各自不同的。
所以说函数的上下文的产生,并不由函数的定义来决定,而是由函数的
调用来决定。
3.3.4 构造器调用模式(Invocation as a constructor)作为构造器被调用,函数的定义并没有什么不同,不同的地方在于调用
的方式。
如果想让一个函数作为构造器被调用,需要用到 new 关键字。
例如,我们的 creep 函数 function creep(){ return this;} 如果我们想让 creep 函数作为构造器来被调用,我们需要这么写: new creep(); 但是,就算我们用构造器的模式来调用 creep(),这个函数也不适合作
为构造器。
让我来讨论下构造器的特性:THE SUPER-POWERS OF CONSTRUCTORS
将一个函数作为构造器来调用是一个很有用处的亮点,以下是这些亮点:
1.一个新的空对象被创造出来
2.这个对象被传递给这个构造器作为 this 参数,也就是说这个对
象是这个构造器函数的上下文
3.如果没有显性的return语句,这个新的对象则会被隐式的return,
并成为这个构造器的值。
这些正是说明了 creep()函数不适合作为构造器。
构造器的目的是为了创建一个新的对象,并且 set it up,返回它,让它
作为构造器的值。
让我构建一个更加有意义的函数:一个可以 set up the skulking ninjas
例子 3.4