`
lgx2351
  • 浏览: 175309 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

js学习笔记2-函数

阅读更多

2. 函数
2.1函数直接量
函数直接量是用作表达式,而不是用作语句,它无需指定函数名。与函数写法的比较:

function f(){} 
var f = function(){}

 
2.2函数的参数
Js中函数的参数个数和类型是可以很任意的,这就需要用于实质的情况进行相应的判断处理。

可选参数

如果一个函数的参数是可选的,那么如果没有传的话,则是underfined的值,则在函数里用||对它进行赋默认值。这种写法很常用。

用对象来作为函数的参数

当函数的参数较长的用,且常与||一起使用。

参数类型

如果对函数的参数类型有着严格的要求,那么记得一定要在函数内对类型做判断,如果类型不正确,则抛出异常来报告这一事实。如arraycopy()方法,期望的参数是数组,则如果传入的不是数组,那么需要抛出。

再比如我们计算一个数组所有元素的和,如果是在以前,程序里是数组里预先是判定所有的元素都是数值的,然后根据数值的元素的情况去求和。但是,很多时候开发者并不是一个人,可能你要处理的数组是别人开个接口提供给你的,或者你是从数据库去取出数据来构造出数组,这时候你就不能都把元素当作数值来判断,必须对传入的是否是数组,及元素是否是数值进行相应的判断,如果元素有underfined或null时忽略,或元素包含有不是数值时给出提示,或传入的值不是数组时给出提示。具体的代码如下:

function ArrayUserCommMgr{}
ArrayUserCommMgr.prototype={
	isArray:function(a){
 		var result = false;
 		if((a instanceof Array)||(a && typeof a == "object" && "length" in a)){
			result = true;
		}
		return result;
 	},
	getSum:function(a){
		if (arrayUserCommMgr.isArray()){ 
			var total = 0;
			for(var i = 0; i < a.length; i++) {
				var element = a[i];
				if (!element) continue;  // ignore null and undefined elements
				if (typeof element == "number"){
					total += element;
				}else{
					throw new Error("sum(): all array elements must be numbers");
				}
			}	
		}else{
			throw new Error("sum(): argument must be an array");
		}	
	}	
}

 

以上代码注意的是:

1、用((a instanceof Array)||

           (a && typeof a == "object" && "length" in a))

来判断是否传入的是数组(instanceof Array),或类似数组的对象((a && typeof a == "object" && "length" in a))

2、元素如果是underfined或null,则不管,继续执行函数(continue)。

3、元素如果是数值,则相加。数值用:

typeof element == "number"

4、元素如果含有非数值,则提示出来(throw new Error(“”))。

以下函数对于传入的参数进行求和,它把所有的类型情况都考虑到了,好好理解:

function flexisum(){
    var total = 0;
    for(var i=0;i<arguments.length;i++){
       var element = arguments[i];
       if(!element) continue;
       var n;
       switch(typeof element){
           case "number":
              n = element;
              break;
           case "object":
              if(element instanceof Array){
                  n = flexisum.apply(this,element);
              }else{
                  n = element.valueOf();
              }
              break;
           case "function":
              n = element();
              break;
           case "String":
              n = parseFloat(element);
              break;
           case "Boolean":
              n = NaN;
              break;
       }
    }
    if((typeof n == "number")&&(!isNaN(n))){
       total += n;
    }else{
       throw new Exception("无法转换元素"+element);
    }
    return total;
}

 

函数的参数里内在的Arguments对象

1、  arguments对象是函数内在的对象,arguments是一个标识符。

2、  arguments对象是一个类似于数组的对象(类似于数组指的是首先是一个object,然后它具有length属性),它是通过数目,而不是通过名字(说明取得arguments的值只能通过索引来取,不能通过名字来取,因为参数的名字可以随便取的,所以无法取得参数的名字,其实取名字也没有什么意义)来取值。

3、  arguments对象有什么用?一是用来检测调用函数所传入的参数是否是定义要求的个数。如果不是,则抛出异常,这对于对调用传入参数个数有严格要求的情况很有用,如:

function f(a,b,c){
if(arguments.length>3)
        throw new Error(“对不起!传入的参数个数有误!”);
}

 

二是可以传入任意的参数的情况还对参数进行操作,如传入若干个参数,得到所有传入的参数的总和,用for循环即可了,如前面的求和函数flexisum()。这时,这种函数我们叫它可变参数函数(注意:可变参数函数不允许通过0参数方式来调用)。

4、  对arguments对象的赋值也会影响到参数的值。

5、  对arguments对象的操作除了处理它的元素外,它有一个callee属性比较常用,它引用的是正在执行的函数。一般用它来对未命名的函数递归地调用自己。如以下计算阶乘:

function(x){
	return x * arguments.callee(x-1);
}

2.3把函数做为数据
1、把函数用做数据的写法其实在程序里很常用,可且用得很多,需要较为好的熟悉。

2、有时候,我们写函数并不需要用到这个函数的函数名,这时候把它作为数据赋值给其它变量,也会执行这个函数,这时候就不需要函数名了。

3、把函数作为数据,可以把它函数赋值给一个变量,可以把它做为一个对象的属性(这点在写ptototype里常用),可以把它放在数组里,可以把它做为参数传递给一个函数等等。总之,可以把它做为数据来使用。如:

把函数传给变量:

Var a = function(x){x*x}

把函数做为对象的属性:

Var o = new object();

o.square = function(x){x*x}

把函数放在数组里:

Var a = new Array(10);

A[0] = function(){}

1、  以下是一个较为完整的例子,好好理解(学习写法):

function add(x,y) { return x + y; }
function subtract(x,y) { return x - y; }
function multiply(x,y) { return x * y; }
function divide(x,y) { return x / y; }

function operate(operator, operand1, operand2)
{
    return operator(operand1, operand2);
}

var i = operate(add, operate(add, 2, 3), operate(multiply, 4, 5));

//以下是另一种写法
var operators = {
    add:      function(x,y) { return x+y; },
    subtract: function(x,y) { return x-y; },
    multiply: function(x,y) { return x*y; },
    divide:   function(x,y) { return x/y; }
};
function operate2(op_name, operand1, operand2)
{
    if (typeof operators[op_name] == "function")
        return operators[op_name](operand1, operand2);
    else throw "unknown operator";
}
var j = operate2("add", "hello", operate2("add", " ", "world"))

 

以上代码可以学习的有很多:

1、  把一些相关的操作组合在一起,用对象来组合。要调用哪个函数时传入这个对象的标识就可以了。(但是感觉有些麻烦了)

2、  如果要调用一个函数,而这个函数用数据的方式来写。可以先判断typeof是否是funciton,是的话,用对象的标识来得到函数,再传入数据来调用:

    if (typeof operators[op_name] == "function")
        return operators[op_name](operand1, operand2);
    else throw "unknown operator";

  

3、  前面一段是用传统的写法,用函数名。后面是把函数当作数据的写法。前面的写法里也可以把参数名做为参数传到函数里去:

function operate(operator, operand1, operand2)
{
    return operator(operand1, operand2);
}

2.4把函数作为方法
定义一个函数,并把它作为方法来引用,这种写法很常用。
或者,把一个函数作为一个对象的属性,然后调用这个对象的方法,如:
var o.m = f;
o.m();
把函数作为方法来调用要有一个属性很重要,它是this。在一个方法体内,this指的是用来调用这个方法的对象。
当一个函数作为方法来被调用时,记得其实隐藏的传递一了一个参数,即调用函数的对象。
2.5构造函数
构造函数的定义是:是初始化对象的属性并且和new一起来使用的一个函数。当new 它时,是创建了一个object,且这个new的object之后可以用this来传递。
2.6函数的属性与方法
prototype

函数最重要的且最常用的属性是原型prototype:
每个函数都有prototype属性,它引用的是预定义的原型对象。这个原型对象在new一个object时起作用,也就是当你 new调用一个构造函数时起作用。这个原型对象在你定义自己的对象类时也常用,也起到了很重要的作用。
length
函数也有length属性,只是我们比较少用,它指的是这个函数在定义是所指定的参数的个数,而不是像arguments的length一样指的是实质传入函数的参数的个数。因此,我们可以写个函数,用来指定传入的参数个数是否是指定的,从而对那些对参数个数有严格要求的函数的调用进行控制:

function check(){
 var expectedNum = arguments.callee.length;
 var actedNum = arguments.length;
 if(parseInt(expectedNum)!=parseInt(actedNum)){
  throw new Error(”调用的参数与函数定义时期望的参数个数不符合!”);
 }
}

 
注意上面是用arguments的callee属性来引用自身(因为在函数体内其它的方法无法指定函数本身)。
定义自己的函数属性
这里的“定义自己的函数属性”指的是:有时你想用一个全局变量时,而这个全局变量只在某个函数体内使用,并没有在其它的函数体内被使用。这时候,可以考虑把它定义为这个函数的属性并当作全局变量来使用,如下:

f.counter = 0;
function f(){
 return f.counter++;
}

 
在上面的代码中把counter不作为全局变量,而作为f的属性,在f的函数体内用f.counter来引用这个变量,它也起到了全局变量的效果,可以保存之前变化的值。
方法apply()和call()(apply和call较难理解,可参看收藏的相关内容)
1、 使用这两个函数可以像调用其它对象的方法一样来调用函数。
2、 第一个参数是要调用的函数的对象,在函数体内这一参数是this的值(不太理解)
3、 其它的参数是参数值。Apply与call一样,只不过传递的参数是数组。
如:
f.call(o,1,2)相当于:
o.m = f;
o.m(1,2);
delete o.m;
又如:
Var maxNum = Math.max.apply(null,array_of_num);

分享到:
评论
2 楼 lgx2351 2009-09-03  
wtusmchen 写道
blog写的不错啊,以后多过来学习:)

多谢wtusmchen大哥的鼓励!只是一些总结,望多多指教!
1 楼 wtusmchen 2009-09-03  
blog写的不错啊,以后多过来学习:)

相关推荐

    JavaScript高级程序设计2,学习笔记---第一篇

    这篇学习笔记将带你探索JavaScript的核心概念,包括变量、数据类型、控制流、函数、对象和类等,这些都是构建复杂应用程序的基础。 首先,我们要了解JavaScript的基础语法。在JavaScript中,变量是存储数据的容器,...

    第四章(js高级程序设计学习笔记)----2

    在本节中,我们将深入探讨JavaScript的高级程序设计,特别是关注"第四章(js高级程序设计学习笔记)----2"的主题。这一章很可能涵盖了JavaScript的核心概念,包括原型链(Prototype Chaining)。通过阅读名为...

    达内学习笔记----PHP基础+MYSQLS基础+JS笔记整理.docx

    总结,这份学习笔记涵盖了PHP的基础语法、数学和日期处理、字符串操作,以及MySQL和JavaScript/jQuery的基本知识,是一份全面的Web开发学习资料。通过深入理解和实践这些内容,开发者可以提升自己的Web开发技能。

    JavaScript学习笔记_js常用函数封装_js包.zip

    本压缩包“JavaScript学习笔记_js常用函数封装_js包.zip”包含了对JavaScript基础及进阶技巧的学习资料,特别关注了函数封装和模块化开发实践。 首先,`tool.js`可能是一个实用工具函数集合,封装了一些常见的...

    前端学习笔记-黑马程序员JS

    "前端学习笔记-黑马程序员JS" 本资源主要介绍了 JavaScript 的基本概念和语法,包括变量、数据类型、运算符、流程控制、数组、函数、对象、内置对象等知识点。 变量 在 JavaScript 中,变量可以在三种位置书写:...

    Cocos2D-X开发学习笔记-时间调度schedule函数的使用

    本篇学习笔记主要关注的是Cocos2D-X中的时间调度机制,特别是如何使用`schedule`函数进行周期性任务的执行。 在Cocos2D-X中,时间调度是游戏循环的重要组成部分,它允许开发者在特定的时间间隔内执行某些函数或操作...

    js 笔记 javascript 学习笔记

    本学习笔记将深入探讨JavaScript的核心概念,包括变量、数据类型、操作符、控制流程、函数、对象、数组、原型链、闭包等,并结合实际示例,如my.js、order.js、login.js等文件,来讲解其在实际项目中的应用。...

    Cocos2d-x学习笔记

    - 学习脚本语言:虽然Cocos2d-x支持多语言开发,但了解JavaScript、Lua等脚本语言,可以快速实现游戏功能和逻辑。 Cocos2d-x框架除了Windows平台外,还支持iOS、Android、Mac OS X、Web等平台,初学者在掌握了...

    HTML CSS JS 学习、git-笔记.zip

    此外,该资源还提供了关于版本控制工具Git的学习笔记,帮助你更好地进行代码管理和协作开发。总之,【HTML CSS JS 学习、git-笔记.zip】是一个宝贵的学习资源,旨在帮助前端开发者提升技能水平,实现更高效的开发...

    jqGrid学习笔记1 - - - - jqGrid英语PDF文档

    这个学习笔记主要围绕“jqGrid学习笔记1”展开,内容来源于jqGrid的英文PDF文档,结合了源码解析和实用工具的介绍。 首先,jqGrid支持多种数据源,包括JSON、XML、HTML、CSV等,这使得它能灵活地与各种后端服务进行...

    Javascript学习笔记-学JS的一手教程

    JavaScript学习笔记 JavaScript是一种强大的、跨平台的编程语言,主要用于为网页和应用程序添加交互性。在Web开发中,JavaScript与HTML和CSS一起构成了基础的三驾马车。本教程将帮助初学者理解JavaScript的核心概念...

    JavaScript学习笔记

    JavaScript是一种广泛应用于网页和网络应用的脚本语言,它在浏览器端...通过阅读"JavaScript从入门到精通学习笔记.docx"文档和解压"Chapter2.rar",你将深入探索以上各个知识点,逐步成为一名熟练的JavaScript开发者。

    Ajax学习笔记---3种Ajax的实现方法【推荐】

    在JavaScript中,可以通过创建一个新的XMLHttpRequest对象,设置onreadystatechange事件处理函数,然后调用open和send方法来发送请求。例如: ```javascript var xhr = new XMLHttpRequest(); xhr....

    JavaScript-学习笔记.pdf

    以上是JavaScript学习笔记中提到的一些核心知识点,通过对这些知识点的理解和熟练应用,可以为进一步学习和掌握JavaScript打下坚实的基础。在实际开发过程中,结合具体的项目需求,这些知识会得到更深入的拓展和应用...

    个人Javascript学习笔记 精华版

    本资源为个人Javascript学习笔记的精华版,涵盖了Javascript的基础知识、事件处理、对象和系统函数、浏览器对象等方面的内容。下面是对每个知识点的详细说明: 1. 什么是JavaScript? JavaScript是一种脚本语言,...

    JavaScript学习笔记-适合初学者

    本学习笔记专为初学者设计,旨在帮助新接触JavaScript的人快速掌握这门语言的核心概念和实用技巧。 首先,"JavaScript特效.chm"可能是一份关于JavaScript实现的各种网页特效的教程。这些特效可能包括图片轮播、下拉...

    林信良学习笔记之-AjaxGossip

    **AjaxGossip学习笔记概述** Ajax(Asynchronous JavaScript and XML)是一种在无需刷新整个网页的情况下,能够更新部分网页的技术。这种技术通过JavaScript与服务器进行异步数据交换,使得用户能够获得更加流畅、...

    Cocos2D-X开发学习笔记-触屏事件使用示例

    本学习笔记将深入探讨如何在Cocos2D-X中处理触屏事件,让游戏能够响应用户的触摸操作。 首先,我们要了解Cocos2D-X中的触摸事件处理机制。在Cocos2D-X中,触屏事件主要通过`Touch`类和`TouchEvent`类来实现。`Touch...

    前端学习(四)——javascript学习笔记(二)函数

    前端学习——javascript学习笔记(二)函数

    javascript入门学习笔记

    这些只是JavaScript学习笔记的一部分,深入理解并熟练运用这些概念,将为JavaScript编程打下坚实的基础。随着学习的深入,还会接触到更多高级特性和框架,如闭包、原型链、AJAX、jQuery、Vue.js、React.js等,这些都...

Global site tag (gtag.js) - Google Analytics