第4章-函数(1)

函数对象 Functions

对象是“名/值”对的集合并拥有一个连到原型对象的隐藏链接。对象字面量产生的对象链接到Object.prototype。函数对象连接到Function.prototype(该原型对象本身链接到Object.prototype)。每个函数在创建时会附加隐藏属性:函数的上下文和实现函数行为的代码。

每个函数对象在创建时也有一个prototype属性,它的值是一个拥有constructor属性且值即为该函数的对象。

函数字面量 Function Literal

函数对象通过函数字面量来创建

1         var add = function (a,b){
2             return a+b;
3         };

一个内部函数除了可以访问自己的参数和变量,同时它也能自由访问把它嵌套在其中的父函数的参数和变量。通过函数字面量创建的函数对象包含一个连到外部上下文的链接。这被称为闭包。

调用 Invocation

调用一个函数会暂停当前函数的执行,传递控制权和参数给新函数。除了声明定义的形式参数,每个函数还接受两个附加的参数:this和arguments。参数this在面向对象编程中非常重要,它的值取决于调用的模式。在JavaScript中一共有4种调用模式:方法调用模式、函数调用模式、构造器调用模式和apply调用模式。这些模式在如何初始化关键参数this上存在差异

方法调用模式 The Method Invocation Pattern

当一个函数被保存为一个对象的属性时,我们称它为一个方法。当一个方法调用时,this被绑定到该对象。

 1         var myObject = {
 2             value: 0,
 3             increment: function (inc){
 4                 this.value += typeof inc === ‘number‘ ? inc : 1;
 5             }
 6         };
 7
 8         myObject.increment();
 9         console.log(myObject.value); //1
10
11         myObject.increment(2);
12         console.log(myObject.value); //3

方法可以使用this访问自己所属的对象,所以它能从对象中取值或对对象进行修改。通过this可取的它们所属对象的上下文的方法称为公共方法

函数调用模式 The Function Invocation Pattern

当一个函数并非一个对象的属性时,那么它就是被当做一个函数来调用的:

1     var sum = add(3,4); //sum的值为7

以此模式调用函数时,this被绑定到全局对象。这是语言设计上的一个错误,应当一个内部函数被调用时,this应该被绑定到外部函数的this变量。比如:

 1         var value = 2;
 2
 3         var test = {
 4             value:100,
 5             increment:function(){
 6                 this.value = this.value + 100;
 7                 var output = function(){
 8                     console.log(this.value);
 9                 };
10                 output();
11             }
12         };
13
14         test.increment(); //2

可以看到最后输出的结果是 2 ,this.value指向的是全局变量中的value。有一个很容易的解决方案就是在对象中将this赋值给另外一个变量

 1         var value = 2;
 2
 3         var test = {
 4             value:100,
 5             increment:function(){
 6                 var that = this;
 7                 that.value = that.value + 100;
 8                 var output = function(){
 9                     console.log(that.value);
10                 };
11                 output();
12             }
13         };
14
15         test.increment(); //200

构造器调用模式 The Constructor Invocation Pattern

如果在一个函数前面带上new来调用,那么背地里将会创建一个连接到该函数的prototype成员的新对象,同时this会被绑定到那个新对象上。

 1         //创建一个名为Quo的构造器函数,他构造一个带有status属性的对象
 2         var Quo = function (string){
 3             this.status = string;
 4         };
 5
 6         Quo.prototype.get_status = function(){
 7             return this.status;
 8         };
 9
10         var myQuo = new Quo("confused");
11         console.log(myQuo.get_status()); //confused

一个函数,如果创建的目的就是希望结合new前缀来使用,那它被称为构造器函数,按照约定,他们保存在以大写格式命名的变量里。

Apply 调用模式 The Apply Invocation Pattern

apply方法让我们构建一个参数数组传递给调用函数。它接受两个参数,第1个是要绑定给this的值,第2个就是一个参数数组。

1         var array = [3,4];
2         //apply第一个参数传递为null,并不是说将add函数的运行上下文环境设置为null,而是设置为全局对象window
3         var sum = add.apply(null,array); //sum的值为7
4
5         var statusObject = {
6             status: ‘A-OK‘
7         };
8         //statusObject并没有继承自Quo.prototype,但我们可以在statusObject上调用get_status方法,尽管statusObject没有这个方法
9         var status = Quo.prototype.get_status.apply(statusObject);//status的值为‘A-OK‘

参数 Arguments

函数可以通过此参数访问所有它被调用时传递给它的参数列表,包括哪些没有分配给函数声明时定义的形式参数的多余参数

1         var sum = function(){
2             var i,sum = 0;
3             for(i=0;i<arguments.length;i++){
4                 sum += arguments[i];
5             }
6             return sum;
7         }
8
9         console.log(sum(10,20,56,48,2,36,98)); //270

返回 Return

一个函数总是会返回一个值,如果没有指定返回值,则返回underfined

如果函数调用时在前面加上了new前缀,且返回值不是一个对象,则返回this(该新对象)

异常 Exceptions

异常是干扰程序正常流程的不寻常,当发现这样的事故,应该抛出一个异常:

 1         var add = function(a,b){
 2             if(typeof a !== ‘number‘ || typeof b !== ‘number‘){
 3                 throw{
 4                     name: ‘The Most Serious Error‘,
 5                     message: ‘you are too handsome‘,
 6                     from: ‘Qq‘
 7                 };
 8             }
 9             return a + b;
10         }
11
12         //throw语句中断函数的执行,它应该抛出一个exception对象,该对象包含一个用来识别异常类型的name属性和一个描述性的message属性。你也可以添加其他的属性。
13         //该exception对象被传递到一个try语句的catch从句:
14
15         var try_it = function(){
16             try{
17                 add("seven");
18             }catch(e){
19                 console.log(e.name + ": " + e.message + "  " + e.from);
20             }
21         }
22
23         try_it(); //The Most Serious Error: you are too handsome  Qq

如果在try代码块内抛出了一个异常,控制权就会跳转到它的catch从句。一个try语句只会有一个捕获所有异常的catch代码块。如果你的处理手段取决于异常的类型,那么异常处理器必须检查异常对象的name属性来确定异常的类型

扩充类型的功能 Augmenting Types

JavaScript允许给语言的基本类型扩充功能。举例来说我们可以给Function.prototype增加方法来使得该方法对所有的函数可用:

 1         Function.prototype.method = function(name,func){
 2             this.prototype[name] = func;
 3             return this;
 4         };
 5
 6         //给Number.prototype增加一个integer方法来改善它,他会根据数字的正负来判断使用Math.ceiling还是Math.floor。
 7
 8         Number.method(‘integer‘,function(){
 9             return Math[this < 0 ?‘ceil‘ : ‘floor‘](this);
10         });
11
12         console.log((10/3).integer()); //3

基本类型的原型式公用的,所以在类库混用时务必小心。一个保险的做法就是只在确定没有该方法时在添加它

1         Function.prototype.method = function(name,func){
2             if(!this.prototype[name]){
3                 this.prototype[name] = func;
4             }
5             return this;
6         };
时间: 2024-10-12 19:37:39

第4章-函数(1)的相关文章

离散数学--第5章 函数

第5章 函数• 5.1 函数定义及其性质• 5.2 函数的复合与反函数 5.1 函数定义及其性质• 5.1.1 函数的定义– 函数定义– 从A到B的函数• 5.1.2 函数的像与完全原像• 5.1.3 函数的性质– 函数的单射.满射.双射性– 构造双射函数 满射:就是Y全用了. 单射:一对一.说明是单调的. 双射:即使单射又是满射. 1 5.2 函数的复合与反函数• 5.2.1 函数的复合– 函数复合的基本定理及其推论– 函数复合的性质• 5.2.2 反函数– 反函数存在的条件– 反函数的性质

第七章 函数

第七章  函数 7.1  函数的基础知识 要使用函数,必须完成如下工作: Ø  提供函数定义 Ø  提供函数原型 Ø  调用函数 7.1.1  函数的定义 函数总体来说可以分为两类,一类是没有返回值的,另一类是具有返回值的,两类的函数定义的格式如下 void functionName(parameterList) { statement(s) return; //可以有也可以没有 } typeName functionName(parameterList) { statement(s) retu

紫书第4章 函数和递归

1  序 系统的整理下第四章的学习笔记.同上次一样,尽量在不依赖书本的情况下自己先把例题做出来.这次有许多道题代码量都比较大,在例题中我都用纯C语言编写,但由于习题的挑战性和复杂度,我最终还是决定在第五章开始前,就用C++来完成习题.不过所有的代码都是能在C++提交下AC的. 在习题中,我都习惯性的构造一个类来求解问题,从我个人角度讲,这会让我的思路清晰不少,希望自己的一些代码风格不会影响读者对解题思路的理解. 其实在第四章前,我就顾虑着是不是真的打算把题目全做了,这些题目代码量这么大,要耗费很

Welcome to Swift (苹果官方Swift文档初译与注解三十五)---248~253页(第五章-- 函数 完)

Function Types as Return Types (函数类型作为返回值类型) 一个函数的类型可以作为另一个函数的返回值类型.可以在一个函数的返回值箭头后面写上一个完整的函数类型. 例如: 下面的例子定义了两个简单的函数,分别为stepForward 和 stepBackward.其中stepForward函数返回值比它的输入值多1,stepBackward函数返回值比它输入值少1.这两个函数的 类型都是(Int) -> Int: func stepForward(input: Int

C++ Primer学习总结 第6章 函数

第6章 函数 1.    函数最外层作用域中的局部变量不能使用与函数形参一样的名字,因为它们属于同一个作用域范围. 2.    局部静态变量的生命周期: 在整个程序的执行路径第一次经过对象定义语句时初始化,并且直到整个程序终止时才被销毁,在此期间即使对象所在函数结束执行也不会对它有影响. 3.    如果重载的函数的参数只有顶层const区别,那么是错误的: 如果有底层const区别可以算作重载. 4.    如果函数的参数要使用引用(且不会改变引用对象的值),那么应该定义成常量引用. 因为使用

《javascript语言精粹》——第4章函数

函数就是对象 [1].函数字面量即(函数表达式)包括四部分: 第一部分:保留字function: 第二部分:函数名称,可有可无: 第三部分:包围在一对小括号的一组参数,参数用逗号隔开: 第四部分:包围在一对花括号的一组语句,是函数的主体: 函数字面量可以出现在任何允许表达式出现的地方. [2].调用有四种调用模式: 除了声明时定义的形参,每个函数接收附加的的参数:this和arguments  ,this的值取决于调用的模式. 第一种:方法调用模式: var aa={ value:0, incr

C++ primer plus读书笔记——第8章 函数探幽

第8章 函数探幽 1. 对于内联函数,编译器将使用相应的函数代码替换函数调用,程序无需跳到一个位置执行代码,再调回来.因此,内联函数的运行速度比常规函数稍快,但代价是需要占用更多内存. 2. 要使用内联函数,需要在: 函数声明前加上关键字inline; 函数定义前加上关键字inline; 3. 程序员请求将函数作为内联函数时,编译器不一定会满足这种需求.它可能认为该函数过大或注意到函数调用了自己(内联函数不能递归). 4. 必须在声明引用变量时进行初始化 int rat = 101; int &

C++ primer plus读书笔记——第7章 函数——C++的编程模块

第7章 函数——C++的编程模块 1. 函数的返回类型不能是数组,但可以是其他任何一种类型,甚至可以是结构和对象.有趣的是,C++函数不能直接返回数组,但可以将数组作为结构或对象的组成部分来返回. 2. 在C++中括号为空意味着不指出参数.在ANSI C中,括号为空意味着不指出参数.在C++中,不指定参数列表时应该用省略号. void say_bye(…); 3.  数组名数组名解释为其第一个元素的地址有一些例外,首先,对数组名使用sizeof将得到整个数组的长度:其次,将地址运算符用于数组名时

Swift 1.1语言第7章 函数和闭包

Swift 1.1语言第7章  函数和闭包 在编程中,随着处理问题的越来越复杂,代码量飞速增加.其中,大量的代码往往相互重复或者近似重复.如果不采有效方式加以解决,代码将很难维护.为 了解决这个问题,人们提出了函数这一概念.使用函数可以将特定功能的代码封装,然后在很多的地方进行使用.本章将会讲解函数和闭包的相关内容.本文选自<Swift 1.1语言快速入门> 7.1  函数介绍 函数是执行特定任务的代码块.使用函数会给开发这带来很多的好处.以下总结了其中两点. 1.结构鲜明,便于理解 如果在一

Welcome to Swift (苹果官方Swift文档初译与注解三十三)---235~240页(第五章-- 函数)

Default Parameter Values (参数默认值) 在定义函数的时候,你可以给任何参数定义一个默认的值,如果定义了默认值,在调用这个函数的时候,你可以忽略这个参数. 注意: 设置参数默认值的时候,需要按照函数的参数列表最后的开始,这可以确保在调用函数的时候,即使没默认值的参数也可以按顺序的对应上,也使得函数在调用的时候更加清晰. 下面的代码例子是join函数的新版本,它使用了默认参数: func join(string s1: String, toString s2: String