概要:本篇博客主要介绍了JavaScript的函数。

1.第一型对象

  JavaScript的函数可以像对象一样引用,因此我们说函数是第一型对象。除了可以像其他对象类型一样使用外,函数还有一个特殊的功能,它们可以被调用。这些调用,通常是以异步的方式进行调用。

2.回调

  回调是高效利用JavaScript必不可少的一部分。

3.函数声明

  如果一个函数不需要用名称进行引用,则不需要对它命名。命名一个函数时,该名称在整个函数声明范围内都是有效的。此外,函数声明在顶层,window对象上的同名属性则会引用到该函数。所有的函数都有一个name属性,该属性保存的是该函数名称的字符串。没有名称的函数也仍然有name属性,只是该属性值为空字符串罢了。

4.作用域与函数

  在JavaScript中,作用域是由function进行声明的,而不是代码块。

  ● 变量声明的作用域开始于声明的地方,结束于所在函数的结尾,与代码嵌套无关。

  ● 命名函数的作用域是指声明该函数的整个函数范围,与代码嵌套无关。

  ● 对于作用域声明,全局上下文就像一个包含页面所有代码的超大型函数。

  函数可以在其作用域范围内提前被引用,但变量不行。

5.函数调用

  有四种不同的方式可以进行函数调用,每种方式都有自己的细微差别。

  ● 作为一个函数进行调用,是最简单的形式。

  ● 作为一个方法进行调用,在对象上进行调用,支持面向对象编程。

  ● 作为构造器进行调用,创建一个新对象。

  ● 通过apply()或call()方法进行调用。

6.函数的形参与实参

  当一个参数列表作为函数调用的一部分时,这些参数会按照函数声明里的形参声明顺序,将参数值分别赋值给这些形参。第一个参数赋值给第一个形参,第二个参数赋值给第二个形参,以此类推。

  如果传入的参数个数与形参数量不一致,JavaScript处理方式如下:

  如果实际传递的参数数量大于函数声明的形参数量,超出的参数则不会配给形参名称。

  例如:假设我们声明了如下函数:

function whatever(a,b,c){...}

  如果我们调用的时候执行whatever(1,2,3,4,5),参数1、2、3会分别赋值给a、b、c,而参数4和5则不会赋值给任何形参。即使这些参数不赋值给形参名称我们也可以获取它们。

  如果声明的形参数量大于实际传递的参数数量,则没有对应参数的形参会赋值为undefined。

  例如,如果我们调用whatever(a,b,c)函数的时候执行whatever(1),则a会被赋值为1,而b和c则会被赋值为undefined。

  所有的函数调用都会传递两个隐式参数:arguments和this。

  所谓隐式,也就意味着这些参数不会显示列在函数签名里,但它们是默默地传递给函数并存在于函数作用域内。在函数内部,它们可以像其他显示命名的参数一样使用。

7.arguments与this

  arguments:

    arguments参数是传递给函数的所有参数的一个集合。该集合有一个length属性,其值是全部参数的个数,单个参数值可以像访问数组索引一样进行获取,例如:arguments[2]则表示获取第三个参数。但是不要将arguments参数作为数组进行调用。它只是一个类数组结构。

  this:

  一个函数被调用时,除了传入函数的显示参数外,名为this的隐式参数也被传入了函数。this参数引用了与该函数调用进行隐式关联的一个对象,被称之为函数上下文。JavaScript中的this依赖于函数的调用方式。

8.不同调用方式

  ◆ 作为函数进行调用

  这种方式通常发生在函数上使用()操作符进行调用的时候,应用了()操作符的表达式并没有将函数作为对象的一个属性。如:

function ninja(){};
ninja(); var samurai = function(){};
samurai();

  以这种方式调用时,函数的上下文是全局上下文——window对象。

  ◆作为方法进行调用

  当一个函数被赋值给对象的一个属性,并使用引用该函数的这个属性进行调用时,那么函数就是作为该对象的一个方法进行调用的。如:

var o = {};
o.whatever = function(){};
o.whatever();

  一个方法所属的对象在该方法体内可以以this的形式进行引用。将函数作为对象的一个方法调用时,该对象就变成了函数上下文,并且在函数内部可以以this参数的形式进行访问。

  与作为函数进行调用对比,"作为函数"进行调用所指的函数是定义在window上的,而且调用的时候不必再需要window的一个引用了。除了不再需要隐式的window引用外,这两种方式是一样的。

  注意:函数的上下文随着调用方式的不同而改变,而不是取决于函数是怎样声明的。

  ◆作为构造器进行调用

  将函数作为构造器进行调用它并没有什么特别的地方,构造器函数的声明和其他函数声明一样,不同的地方在于如何调用该函数。将函数作为构造器进行调用,我们要在函数调用前使用new关键字。如:

function creep(){ return this; }

  如果我们要将creep()函数作为构造器进行调用,则要这样调用:

  new creep();

  但是,即便我们可以将creep()函数作为构造器进行调用,它也不是一个特别适合作为构造器进行调用的函数。

  将函数作为构造器进行调用,是JavaScript的一个超级特性,因为构造器调用时,如下特殊行为就会发生。

    ● 创建一个新的空对象。

    ● 传递给构造器的对象是this参数,从而成为构造器的函数上下文。

    ● 如果没有显式的返回值,新创建的对象则作为构造器的返回值进行返回。

  构造器的目的是要创建一个新对象并对其进行设置,然后将其作为构造器的返回值返回,任何干扰这种意图的都不适合作为构造器。

  ◆使用apply()和call()方法进行调用

  在函数调用的时候,JavaScript为我们提供了一种方式,可以显式指定任何一个对象作为其函数上下文。JavaScript的每个函数都有apply()和call()方法,使用任何其中一个方法,我们都可以实现这种功能。

  通过函数的apply()方法来调用函数,我们要给apply()传入两个参数:一个是作为函数上下文的对象,另一个是作为函数参数所组成的数组。call()方法的使用方式类似,唯一不同的是,给函数传入的参数是一个参数列表而不是单个数组。如:

function juggle(){
var result = 0;
for(var n = 0; n < arguments.length; n++){
result += arguments[n];
}
this.result = result;
} var ninja1 = {};
var ninja2 = {}; juggle.apply(ninja1,[1,2,3,4]);
juggle.call(ninja2,5,6,7,8);

JavaScript忍者秘籍——函数(上)的更多相关文章

  1. JavaScript忍者秘籍——函数(下)

    概要:本篇博客主要介绍函数的一些类型以及常见示例 1.匿名函数 使用匿名函数的常见示例: window.onload = function(){ assert(true,'power!'); }; / ...

  2. 深入理解JavaScript中的函数操作——《JavaScript忍者秘籍》总结

    匿名函数 对于什么是匿名函数,这里就不做过多介绍了.我们需要知道的是,对于JavaScript而言,匿名函数是一个很重要且具有逻辑性的特性.通常,匿名函数的使用情况是:创建一个供以后使用的函数.简单的 ...

  3. JavaScript忍者秘籍——原型

    概要:本篇博客主要介绍JavaScript的原型 1.对象实例化 - 初始化的优先级 初始化操作的优先级如下: ● 通过原型给对象实例添加的属性 ● 在构造器函数内给对象实例添加的属性 在构造器内的绑 ...

  4. JavaScript忍者秘籍——闭包

    概要:本篇博客主要介绍了JavaScript的闭包 1.闭包的工作原理 简单地说,闭包就是一个函数在创建时允许该自身函数访问并操作该自身函数之外的变量时所创建的作用域. 例如: var outerVa ...

  5. JavaScript忍者秘籍——运行时代码求值

    1. 代码求值机制 JavaScript中,有很多不同的代码求值机制. ● eval()函数 ● 函数构造器 ● 定时器 ● <script>元素 - 用eval()方法进行求值 作为定义 ...

  6. JavaScript忍者秘籍——驯服线程和定时器

    1.定时器和线程 - 设置和清除定时器 JavaScript提供了两种方式,用于创建定时器以及两个相应的清除方法.这些方法都是window对象上的方法. 方法 格式 描述 setTimeout   i ...

  7. javascript 忍者秘籍读书笔记

    书名 "学徒"=>"忍者" 性能分析 console.time('sss') console.timeEnd('sss') 函数 函数是第一类对象 通过字 ...

  8. javascript 忍者秘籍读书笔记(二)

    闭包的私有变量 function Ninja() { let feints = 0; this.getFeints = function () { return feints }; this.fein ...

  9. 【JavaScript忍者秘籍】定时器

随机推荐

  1. crontab 实现定时脚本执行完毕再执行下一次

    0 4 * * 1 flock -xn /tmp/oneSendTemp.lock -c /home/check_a/h_demand.sh > /dev/null 2>&1

  2. JavaScript的this详解

    1.全局作用域下的this: 2.一般函数与严格模式下的函数的this: 3.当函数的this作为对象的方法的情况下: 4.对象原型链上的this: 对象P的原型指向o, p.a与p.a创建对象p的属 ...

  3. OSI模型第四层传输层--TCP协议

    1.传输层2个协议tcp和udp 2.tcp的可靠性(挂号信). 面向链接的:类似寄挂号信,对方收到了并且能够确认.所以也是可靠的传输. 最大报文传输:两端可以协商传输报文大小.(协商一个报文的大小) ...

  4. zabbix 安装配置以及漏洞检测脚本

    最近zabbix爆出sql注入漏洞.之前一直没装过.就想着来安装一次.我在centos配置玩玩,记录一下:1.安装LAMP yum -y install httpd  mysql  mysql-ser ...

  5. centos6.5 安装python3.5

    1.CentOS6.5 安装Python 的依赖包 yum groupinstall "Development tools" yum install zlib-devel bzip ...

  6. 安装Genymotion与集成eclipse,最后有集成android studio

    本安装过程从不用到VPN 一切国内网络都可以解决. 首先下载Genymotion,网址  https://www.genymotion.com/account/login/ 首先需要注册,我使用163 ...

  7. SNMP概述–运维必知的协议基础

    一.什么是SNMP?   SNMP是  “Simple Network Management Protocol” 的缩写,中文意思是简单网络管理协议,它是由互联网工作小组在RFC1157中定义的应用层 ...

  8. 在一个form里边同时执行搜索和 execl导出功能

    一个form 分搜索 和 导出<form name="searchform" id="searchform" > <input type=&q ...

  9. 如何通过subId来获取phoneId?

    androidL中使用一张数据表来保存sim卡信息:telephony.db中有一张记录SIM卡信息的表,siminfo: CREATE TABLE siminfo(_id INTEGER PRIMA ...

  10. Git 的版本库创建和修改

    什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改.删除,Git都能跟踪,以便任何时刻都可以追踪历史,或 ...