讲给Android程序员看的前端教程(31)——Function

自定义View系列教程00–推翻自己和过往,重学自定义View
自定义View系列教程01–常用工具介绍
自定义View系列教程02–onMeasure源码详尽分析
自定义View系列教程03–onLayout源码详尽分析
自定义View系列教程04–Draw源码分析及其实践
自定义View系列教程05–示例分析
自定义View系列教程06–详解View的Touch事件处理
自定义View系列教程07–详解ViewGroup分发Touch事件
自定义View系列教程08–滑动冲突的产生及其处理


探索Android软键盘的疑难杂症
深入探讨Android异步精髓Handler
详解Android主流框架不可或缺的基石
站在源码的肩膀上全解Scroller工作机制


Android多分辨率适配框架(1)— 核心基础
Android多分辨率适配框架(2)— 原理剖析
Android多分辨率适配框架(3)— 使用指南


版权声明

  • 本文原创作者:谷哥的小弟
  • 作者博客地址:http://blog.csdn.net/lfdfhl
  • 文本视频教程:http://www.stay4it.com/my/course/37

函数与Function

在JavaScript中函数本身也是一个Function实例。请看如下示例:


<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>函数title>
head>
<body>
	<script type="text/javascript">
		var add=function (a,b){
			var c=a+b;
			document.writeln(a+"+"+b+"="+c+"
"
); } add(9526,1); var result=add instanceof Function; document.writeln("函数是否是Function类的实例? ----> "+result+"
"
);
script> body> html>

运行后效果如下图所示:

讲给Android程序员看的前端教程(31)——Function_第1张图片

所以,从这里也可再次印证:在JavaScript中函数本身也是一个对象,既然是对象那么它就拥有相应的属性和方法。故,在此介绍几个Function中非常常用的属性和方法。

length属性

Function的length属性返回函数的输入参数的个数

arguments属性

Function的arguments代表正在执行的函数的内置属性,它包含了调用该函数时所传入的参数信息。例如:可使用arguments.length得到参数的个数;可利用arguments[index]得到参数的值。

prototype属性

Function的prototype属性保存着函数的原型对象。在英语中单词prototype的意思是"样机",假若你把样机都改了,那么之后以此为蓝本的生产的产品也会随之发生变化。嗯哼,顺着这个单词的本意,我们来看如下示例:


<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>函数title>
head>
<body>
	<script type="text/javascript">
		function Dog(name,color){
			this.name=name;
			this.color=color;
			this.type="犬科";
			this.eat=function(){
				document.writeln("Dog eat bone"+"
"
); } } var xiaobai=new Dog("小白","白色"); xiaobai.eat(); var xiaohei=new Dog("小黑","黑色"); xiaohei.eat();
script> body> html>

定义一个Dog类,Dog具有三个属性:名字,颜色,类别;Dog还有一个方法eat( )。建立两个对象xiaobai和xiaohei再调用其eat( )方法,输出结果如下:

讲给Android程序员看的前端教程(31)——Function_第2张图片

采用该方式来创建对象,可以是可以;但是带来一个弊端:代码的冗余和内存的浪费。比如,在该示例中每生成一个实例,都会重复生成type属性和eat( )方法从而浪费了内存。这时候,prototype(原型对象)就派上用场了。在JavaScript中实例可继承prototype的属性和方法;也就是说:我们可把那些不变的属性和方法直接定义在prototype对象上。现在就利用prototype修改刚才的示例:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>函数title>
head>
<body>
    <script type="text/javascript">
    function Dog(name, color) {
        this.name = name;
        this.color = color;
    }
    Dog.prototype.type = "犬科";
    Dog.prototype.eat = function() {
        document.writeln("Dog eat bone" + "
"
); } var xiaobai = new Dog("小白", "白色"); xiaobai.eat(); var xiaohei = new Dog("小黑", "黑色"); xiaohei.eat();
script> body> html>

在此从结构和效率的角度优化代码,将type属性和eat( )方法定义在了prototype中。

接下来,我们再在Array的prototype添加一个找出最大值的方法getMax。

代码如下:


<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>prototype示例title>
	head>
	<body>
		<script type="text/javascript">
			Array.prototype.getMax = function() {
				//this代表当前对象
				var max = this[0];
				for (var index = 1; index < this.length; index++) {
					if (this[index] > max) {
						max = this[index];
					}
				}
				return max;
			}
			var arr = [62, 44, 17, 9];
			var max = arr.getMax();
			document.write("最大值是:" + max);
		script>
	body>
html>

结果如下:

最大值是:62

其实,从这个角度来看prototype多少有点Java中继承的味道。

call( )和apply( )

call( )和apply( )用于调用当前Function对象并与此同时改变函数内的this指针引用。换句话说:call( )和apply( )切换了函数执行时的上下文(this值)。call( )和apply( )是Function对象的方法,每个函数都能调用它们。先来瞅瞅call( )

call( )

请看如下示例:


<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>函数title>
head>
<body>
	<script type="text/javascript">
    var name="小明";
    var boy={name:"大雄"};
    function introduce(message){
    	document.writeln(message+",我的名字是"+this.name+"
"
); } introduce("hello"); introduce.call(this,"hello"); introduce.call(boy,"大家好");
script> body> html>

在该示例中,有个变量name,有个对象boy;还有一个函数introduce( ),在该函数中用this.name表示当前环境下的name的值,默认情况下该值为"小明"

  • 直接调用introduce( ),请参见代码第14行
    在这种情况下函数introduce( )中的this.name就是指的"小明",这个大家都明白,不再多说。

  • 调用introduce.call(this,“hello”),请参见代码第15行
    这句代码和直接调用introduce( )没多大的区别,只不过明确了上下文环境为this而已。

  • 调用introduce.call(boy,“大家好”),请参见代码第16行
    在此利用call( )切换了执行introduce( )时的上下文环境,此时相当于是boy在调用introduce( ),所以中introduce( )的this指向的是boy对象,this.name就是boy对象中的name

运行后,输出结果如下图所示:

讲给Android程序员看的前端教程(31)——Function_第3张图片

嗯哼,看到这,可能有人对于call还是有些费解,觉得这个玩意有点不太好理解。没事儿,别担心,我们再来看个例子:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>函数title>
head>
<body>
    <script type="text/javascript">
    var name = "小明";
    function introduce(message) {
        document.writeln(message + ",我的名字是" + this.name + "
"
); } var boy = { name: "大雄", introduce: function(message) { document.writeln(message + ",我的名字是" + this.name + "
"
); } }; introduce("hello"); boy.introduce("大家好");
script> body> html>

嘿嘿,请看这个例子:先定义了一个方法introduce(message),然后定义boy对象,并且在该对象中也有一个完全相同的方法introduce(message)。嗯哼,累不累?繁琐不?已经有了为什么还要做重复的工作?站在这个角度可以更好地体会call( )。其实,这也是JavaScript中继承的雏形。

apply( )

apply( )与Function对象的call( )函数作用相同,只不过call( )函数是将Function对象的参数一个个分别传入,而apply( )函数是将Function对象的参数以一个数组或以arguments对象的形式整体传入。其余东西,不再赘述。


函数与类和对象

在这几篇文章中我们学习了JavaScript的函数,类,对象。在此,对这三者的关系做一个梳理和小结。

函数与类

在JavaScript中在定义函数的同时会得到一个与之同名的类。请看如下示例:




	
	函数与类


	


代码详解如下:

  • 定义函数Student,请参见代码第9-15行
    在此定义一个函数的同时得到一个Student类

  • 利用Student创建对象s,请参见代码第16行

  • 调用对象s中的方法,请参见代码第17行

运行后效果图如下所示:

讲给Android程序员看的前端教程(31)——Function_第4张图片

所以,简单地来说:函数名就是类名,函数本身就是类的构造函数,并且可以使用new关键字创建一个实例对象。

函数与对象

在JavaScript中几乎所有东西都是对象;包括我们刚才讲的函数,它本身也是Function的实例!

this关键字

这几篇文章中我们多次用到JavaScript的关键字this,或许有的童鞋在看到这个玩意儿时有点懵。

讲给Android程序员看的前端教程(31)——Function_第5张图片

this?对象?不解啊!啥玩意儿啊!在JavaScript中this指的是调用该函数的对象。在利用构造函数生成一个新对象(object)的过程中this指的就是这个新对象!现在,我们再回过头来看几行已经非常熟悉的代码:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>函数title>
head>
<body>
    <script type="text/javascript">
    var name="小泽";
    function print(){
        document.writeln(this.name);
    }
    print();
    script>
body>
html>

在该示例中:有个变量name,该变量默认属于window。除此以外,还有一个函数print( )。在代码第13行执行了:

print();

嗯哼,请问是谁调用了函数print( )???是window!!!所以,你写成window.print( )也是完全没有错误的。那么,在print( )方法中document.writeln(this.name);这里的this当然指向了window,所以this.name表示了window的name.

你可能感兴趣的:(讲给Android程序员看的前端教程(31)——Function)