as3:Function以及call,apply

Function类在as3中是直接从Object继承下来的,通常开发者定义的每一个function,均可以认为是Function类的一个实例。 

如果硬要跟c#做比较,Function类跟Delegate(委托)有几分相似,均可以达到通过该类型的实例来调用不同方法的目的。 

using System;

namespace FunctionTest
{
    class Program
    {
        private delegate void _delegateType(string name);

        static void Main(string[] args)
        {
            _delegateType d = new _delegateType(helloWorld);
            d("jimmy.yang");

            Console.Read();
        }

        private static void helloWorld(string name) {
            Console.WriteLine("hello,{0}!", name);
        }
    }
}

这段c#代码中,委托_delegateType的实例d,最终调用了具有同样方法签名的方法helloWorld.

来看下as3是怎么做的?

package
{
	import flash.display.Sprite;
	import flash.events.Event;

	public class FunctionTest extends Sprite
	{
		private var _delegate:Function ;
		
		public function FunctionTest()
		{ 
			if (stage){init();}
			else{
				this.addEventListener(Event.ADDED_TO_STAGE,init);
			}
		}
		
		private function init(e:Event=null):void{
			this.removeEventListener(Event.ADDED_TO_STAGE,init);			
			this._delegate = this.helloWorld;
			_delegate("菩提树下的杨过");//hello, jimmy.yang ! 即:相当于c#中"委托"调用"方法"
			
			var jimmy:Object = new Object();
			//定义jimmy对象的一个方法
			jimmy.addSalary = function(addSalary:uint):void{
				trace("姓名:",this.name,",原工资:",this.salary,",新工资:",this.salary + addSalary);
			};
			
			trace(jimmy.addSalary is Function);//true
			trace(typeof jimmy.addSalary);//function
			
			jimmy.name = "jimmy.yang";
			jimmy.salary = 3000;
			jimmy.addSalary(500);//姓名: jimmy.yang ,原工资: 3000 ,新工资: 3500
			
			
			var mike:Object = new Object();
			mike.name = "Mike";
			mike.salary = 5000;	
			jimmy.addSalary.call(jimmy,1000);//姓名: jimmy.yang ,原工资: 3000 ,新工资: 4000
			jimmy.addSalary.call(mike,1000);//姓名: Mike ,原工资: 5000 ,新工资: 6000	
			jimmy.addSalary.apply(mike,[1100]);//姓名: Mike ,原工资: 5000 ,新工资: 6100		
			
			
			_delegate = jimmy.addSalary;
			_delegate.call(mike,1999);//姓名: Mike ,原工资: 5000 ,新工资: 6999
			_delegate.apply(mike,[2999]);//姓名: Mike ,原工资: 5000 ,新工资: 7999
			
			
		}
		
		private function helloWorld(name:String):void{
			trace("hello,",name,"!");
		}
		
		
	}
}

哦,代码有点长,先不用全看完,注意:

this._delegate = this.helloWorld;
_delegate("菩提树下的杨过");//hello, jimmy.yang ! 即:相当于c#中"委托"调用"方法"

这不正是c#中委托调用方法的翻版吗?但即使都当作"委托"来用,也有明显的区别:as3中不用强制定义“委托”的方法签名。

再来看看另外Function类的重要方法call()与apply()

我们知道,每个function最终在执行时,都要有一个上下文环境,也就是this指针在函数执行时,到底指向谁的问题?

var jimmy:Object = new Object();
//定义jimmy对象的一个方法
jimmy.addSalary = function(addSalary:uint):void{
	trace("姓名:",this.name,",原工资:",this.salary,",新工资:",this.salary + addSalary);
};

这里我们动态的给jimmy对象定义了一个addSalary方法,注意addSalary方法体中的this,如果我们用

jimmy.name = "jimmy.yang";
jimmy.salary = 3000;
jimmy.addSalary(500);//姓名: jimmy.yang ,原工资: 3000 ,新工资: 3500

这样调用时,this指针默认就是指向jimmy的,所以this.name自然就是jimmy.yang,而this.salary自然也就是3000,这不废话么?

但是我们可以借助Function类的apply以及call方法,显式改变this指针的指向!注意上面代码中的这一部分:

var mike:Object = new Object();
mike.name = "Mike";
mike.salary = 5000;	
jimmy.addSalary.call(jimmy,1000);//姓名: jimmy.yang ,原工资: 3000 ,新工资: 4000
jimmy.addSalary.call(mike,1000);//姓名: Mike ,原工资: 5000 ,新工资: 6000	

这里我们又搞出了一个mike对象,而且并没有给他定义addSalary方法,但如果系统也要给mike同志临时加工资怎么办? 可以把jimmy对象的addSalary方法应用在mike身上,即jimmy.addSalary.call(mike,1000),最终mike得偿所愿,在原工资5000的基础上加了1000,就成了工资6000 (如果现实中加工资也这么容易就好了)

至于apply方法,作用跟call一样,也可以用来改变函数执行时,this指针的指向,区别在于apply方法要求第二个参数必须是数组形式,即:

jimmy.addSalary.apply(mike,[1100]);

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏从流域到海域

Python 函数

Python的函数与其他语言的函数概念上是一致的,只是形式上有所不同。在面向过程的编程语言中(C语言),函数是代码的基本组成形式,是功能的基本模块;在面向...

22270
来自专栏编程

Python函数之一切皆对象

今天我们要讲的是 对象 避免误会,常老师先澄清一下,这里面说的对象指的是object,不是你的lover,也不是你的sweetheart…… 有的小伙伴可能会觉...

20570
来自专栏机器学习算法与Python学习

“基数排序”展现Python的优雅与简洁

在这儿那桶排序为例目的不是向大家介绍基数排序这种排序方式,是想通过基数排序的实现来展现Python的简洁与优雅。在这儿先简单的介绍一下基数排序,至于具体的内容会...

37750
来自专栏desperate633

LintCode 排列序号题目分析代码

给出一个不含重复数字的排列,求这些数字的所有排列按字典序排序后该排列的编号。其中,编号从1开始。 样例 例如,排列 [1,2,4]是第 1个排列。

9130
来自专栏追不上乌龟的兔子

介绍一些Python str类的方法

上面的代码正确的返回了'0.333333',但是当x = 1 / 2时,由于小数只有一位,这个方案的结果就是'0.5'了,而不是预期中的'0.500000'。

21540
来自专栏于晓飞的专栏

DualPivotQuickSort 双轴快速排序 源码 笔记

这个算法是Arrays.java中给基本类型的数据排序使用的具体实现。它针对每种基本类型都做了实现,实现的方式有稍微的差异,但是思路都是相同的,所以这里只挑了i...

11020
来自专栏工科狗和生物喵

【计算机本科补全计划】《C++ Primer》:类型转换

正文之前 学习,不如爆文?反正晚上也不会学习,某个家伙也对我爱理不理的!!!!(这才是最骚的吧),刚好欠了 C++ Primer太多烂账了。不如赶紧还了! 对了...

31680
来自专栏CVer

排序算法 | 快速排序(含C++/Python代码实现)

排序算法,就是使得序列按照一定要求排列的方法。排序算法有很多,本文将介绍面试中常常被问到的经典排序算法:快速排序,并分别利用C++和Python进行实现。

15100
来自专栏菜鸟前端工程师

JavaScript学习笔记006-作用域0类型转换

10520
来自专栏Brian

C++11基础学习系列一

---- 概述 C++11标准越来越趋于稳定和成熟,国外c++11如火如荼而国内却依然处于观望期。每当提到C++很多程序员都很抵触,特别是学术界的呼声更高一些。...

28340

扫码关注云+社区

领取腾讯云代金券