flash – Function.apply不使用thisArg参数

编程之家收集整理的这篇文章主要介绍了flash – Function.apply不使用thisArg参数编程之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在编写一些Actionscript3代码,试图将方法应用于在运行时确定的对象. Function.applyFunction.call的AS3文档都指出这些函数的第一个参数是在执行函数时将用作“this”值的对象.

但是,我发现在所有情况下,当正在执行的函数是一个方法时,不使用apply / call的第一个参数,’this’总是引用该方法绑定的原始对象.这是一些示例代码及其输出

package
{
    import flash.display.Sprite;    
    public class FunctionApplyTest extends Sprite
    {
        public function FunctionApplyTest()
        {
            var objA:MyObj = new MyObj("A");
            var objB:MyObj = new MyObj("B");

            objA.sayName();
            objB.sayName();

            objA.sayName.apply(objB,[]);
            objA.sayName.call(objB);
        }
    }
}

internal class MyObj
{
    private var _name:String;
    public function MyObj(name:String)
    {
        _name = name;
    }   
    public function sayName():void
    {
        trace(_name);
    }
}

输出

A
B
A
A

对上述代码的一个小修改,以创建一个引用’this’的内联匿名函数,表明当被应用/调用函数不是绑定方法时,会发生正确的行为.

当我尝试在方法上使用它时,我是否使用了apply / call错误? AS3文档专门为此案例提供了代码,但是:

myObject.myMethod.call(myOtherObject,1,2,3);

如果这确实被打破了,除了将目标方法变成函数之外还有其他解决方法(在我看来这会非常难看)吗?

解决方法

它不是一个“bug”,但是调用和应用的文档非常具有误导性,并且在解释最新情况时并没有做得很好.所以这里是对正在发生的事情的解释.

方法与ActionScript中的函数不同.方法被定义为类定义的一部分,方法总是绑定到该实例.参见this link方法.从那里引用:

Methods are functions that are part of a class definition. Once an instance of the class is created,a method is bound to that instance. Unlike a function declared outside a class,a method cannot be used apart from the instance to which it is attached.

因此,当您创建MyObj的新实例时,其所有方法都绑定到该实例.这就是为什么当你尝试使用call或apply时,你没有看到这被覆盖.有关详细信息,请参阅Bound Methods部分.

有关traits对象的解释,请参阅this document,其中actionscript用于解析方法并在幕后使用性能原因可能是罪魁祸首.那个或类方法只是以下ECMAScript模式的语法糖:

var TestClass = function(data) {
    var self = this;
    this.data = data;
    this.boundWork = function() {
        return self.constructor.prototype.unboundWork.apply(self,arguments);
    };
};

TestClass.prototype.unboundWork = function() {
    return this.data;
};

然后:

var a = new TestClass("a");
var b = new TestClass("b");

alert(a.boundWork()); // a
alert(b.boundWork()); // b

alert(a.unboundWork()); // a
alert(b.unboundWork()); // b

alert(a.boundWork.call(b)); // a
alert(a.boundWork.call(undefined)); // a

alert(a.unboundWork.call(b)); // b

甚至更有趣:

var method = a.unboundWork;
method() // undefined. ACK!

VS:

method = a.boundWork;
method() // a. TADA MAGIC!

请注意,无论您使用call或apply传入什么内容,boundWork都将始终在其所属实例的上下文中执行.在ActionScript中,这种行为正是将类方法绑定到其实例的原因.因此,无论它们在何处使用,它们仍然指向它们来自的实例(这使得actionscript事件模型更加“理智”).一旦你理解了这一点,那么解决方法应该变得明显.

对于想要做一些魔术的地方,请避免使用基于ActionScript 3的硬绑定方法支持原型函数.

例如,请考虑以下ActionScript代码

package
{
    import flash.display.Sprite;    
    public class FunctionApplyTest extends Sprite
    {
        public function FunctionApplyTest()
        {
            var objA:MyObj = new MyObj("A");
            var objB:MyObj = new MyObj("B");

            objA.sayName();
            objB.sayName();

            objA.sayName.apply(objB,[]); // a
            objA.sayName.call(objB); // a

            objA.pSayName.call(objB) // b <---
        }
    }
}

internal dynamic class MyObj
{
    private var _name:String;
    public function MyObj(name:String)
    {
        _name = name;
    }   
    public function sayName():void
    {
        trace(_name);
    }

    prototype.pSayName = function():void {
        trace(this._name);
    };
}

注意sayName和pSayName之间的声明差异. sayName将始终绑定到为其创建的实例. pSayName是一个可用于MyObj实例的函数,但未绑定到它的特定实例.

调用和应用的文档在技术上是正确的,只要你谈论的是原型函数而不是类方法,我认为它根本没有提及.

总结

以上是编程之家为你收集整理的flash – Function.apply不使用thisArg参数全部内容,希望文章能够帮你解决flash – Function.apply不使用thisArg参数所遇到的程序开发问题。

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您喜欢寻找一群志同道合、互帮互助的学习伙伴,可以点击下方链接加入:
编程之家官方1群
编程之家官方2群
编程之家官方3群
编程之家官方4群

相关文章

猜你在找的Flash相关文章

Chrome 无法显示使用插件的内容 Chrome 不再支持很多插件。不过网站创建者已经通过更安全的方式,将多数这类功能添加到 Chrome 中。 为什么 NPAPI 插件现在无法正常运行过去,许多插
Flash 开发环境搭建和文字滚动效果实例 一、Flash 开发环境搭建 Flash发布的时候可以将资源(即将库中的元件)集成到swf运行文件中。Flash没有代码自动输入补全功能,因此需要一个英文一
在做web开发中可能会遇到flash遮挡页面中元素的情况,无论怎么设置flash容器和层的深度(z-index)也无济于事,现有的解决方案是在插入flash的embed或object标签中加入”wmo
chrome 45以上不自动播放&quot;非必要&quot;flash的一种可能解决方案chrome 45以上flash被拦截的一种可能解决方案 问题 1、chrome 45以上(包含45)版本默认
加载形式 FLASH加载文件有两种常规方式:一种是URLLoader,可以加载文本、二进制数据或 URL 编码变量形式的数据,然后转换成简单的文本形式或值对字符串形式;一种是Loader,可以将加载的图像文件转换成BitmapData,也可以解析 SWF文件。(Socket, LocalConnection这些非常用类不在讨论范围) 加载的资源应被统一管理以方便调用和重用,管理方式一般有两种:一种
FLASH与传统环境的不同点 MVC最早在1979年的时候第一次被人提出。不过,当时还不存在网络应用的概念。之后当万维网诞生之后,又过了很长时间…… 它并不是自诞生就开始流行的,而改变的原因很简单——因为两个极其流行的开发框架包含了这种模式,它们就是:Struts 和 Ruby on Rails。之后,模仿者蜂拥而至。所以,在人们眼里看来,实际上是先有的Struts,然后才有的MVC,也无怪乎MV
GC和内存泄露无关 垃圾回收,这次是一个被无数人讨论过的传统话题。 Action Script使用的是和Java相似的内存管理机制,并不会即时回收废弃对象的内存,而是在特定时间统一执行一次GC(Gabage Collection)操作来释放废弃对象的内存,避免了重复判断是否需要回收产生的性能问题。 但要注意,这只是决定回收的时机,而不是回收的内容。这个延迟执行内存回收也就是个表面的现象,不管什么时
举个简单的例子,我们要显示一个背包中的道具,需要道具数据库保存ID、类型ID、图片地址、名称、大类别、子类别、质量、说明、是否出售、是否锁 定、道具创建时间、道具持续时间、使用效果定义字符串、可使用等级、堆叠数量、最大堆叠数、出售单价等等,如果按传统做法,就是返回一个二维数组,将所有 信息加载进来,然后直接填充列表,依次填写各项内容。这个做法很很简单,初级程序员就能完成,但代价是,传输数据量会非常
微信公众号搜索 “ 程序精选 ” ,选择关注!
微信公众号搜 "程序精选"关注