zoukankan      html  css  js  c++  java
  • 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]);

    作者:菩提树下的杨过
    出处:http://yjmyzz.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    搞懂分布式技术7:负载均衡概念与主流方案
    搞懂分布式技术6:Zookeeper典型应用场景及实践
    Django学习系列之django分页
    Python学习系列之format用法
    Python进阶系列之怎么写出pythonic的代码
    Python学习系列之内置函数
    域名添加HTTPS
    zabbix学习系列之QQ消息报警
    zabbix学习系列之配置邮件告警
    zabbix学习系列之触发器
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/1782036.html
Copyright © 2011-2022 走看看