以下内容翻译自stackoverflow

链接:

http://stackoverflow.com/questions/7238962/function-apply-not-using-thisarg-parameter

在AS3中,Method(方法)不同于Function(函数),Method是类的一部分,并且是和实例绑定【就是说这个类一旦实例化了,类里定义的Method会绑定这个实例】,看这个链接的第二部分关于Method,引用一部分:

Methods是类定义的functions(函数),一旦类实例化,method会绑定这个实例。函数可以声明在类外,而方法不能脱离类而单独使用。

所以,当我们创建一个MyObj类,类里所有方法绑定这个实例,这就是为什么当你想使用call或apply(的第一个参数),并没有发现this(这个指针)被重新定向为新的对象。看Bound Methods的解释细节。(随后有时间翻译一下bound methods)

看这个链接解释traits object(有时间翻译),actionscript 用来解决method,并用作背后可能会归咎于的性能原因,这个traits object和类方法都仅仅是遵从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!

再来对比:

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

注意看boundWork的执行一直是服从于在它所属的实例,不管你把this改成了什么对象,并用call和apply方法怎么调用。在ActionScript里,这种方式就解释了为什么类里的方法是绑定于它的实例。所以不管这两个方法在哪用,他们始终指向的都是他们所对应的实例(这和actionScript里的事件模型有点类似)。一旦你理解了,那么这种迂回的解决办法就可以被理解了。(这里作者用到一个很有意思的词work-around

(解释:work-around

中文解釋

雖不能根本解決, 但能避開問題的替代方法。

避免問題或困難而旁道而行達到目的。

權宜之計; 應急之策。

原本是電腦術語, 相對於「Fix」而言. 當一個程式有了問題, 找出問題所在然後直接解決它叫做「Fix」; 當問題始終無法解決, 於是想個方法忽略這個問題並使這個問題不致於影響你要用這程式達到的目的, 這樣的方法就叫 Workaround。

英文解釋

workaround means a manner of bypassing a problem caused by a bug without correcting the bug itself.

workaround is similar to "stopgap solution". If there is a problem, a "workaround" doesn‘t eliminate the problem, but it does bypass the problem.

)

(自己主观理解:)

在某些地方,如果你既想需要在类里声明方法,还想用这个方法做自己的事(改变这个方法所指的对象,就是重写this一样),(有空翻译prototype function用法,用的有点抽象)你可以这样写:

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的实例利用,但又不会与特定的实例绑定。

JS中apply和call的联系和区别的更多相关文章

  1. [转]JS中apply和call的联系和区别

    JS中有时常用到 apply 和 call 两个方法,搜索网上很多,整理如下,简单看看这两个联系和区别, 联系: 网上查到关于apply和call的定义:这两个方法都能劫持另外一个对象的方法,继承另外 ...

  2. JS中apply与call的含义与区别

    JavaScript中,apply()与call()的含义一样,均为改变调用函数中的this指向.其中apply()与call()的第一个参数表示所要指向的对象,若调用函数无参数可不写,则默认为win ...

  3. JS中apply和call的应用和区别

    因为object没有某个方法,但是别的对象有,可以借助apply或call像别的对象借方法来操作. 猫吃鱼,狗吃肉,奥特曼打小怪兽. 有天狗想吃鱼了 猫.吃鱼.call(狗,鱼) 狗就吃到鱼了 猫成精 ...

  4. 原生JS中apply()方法的一个值得注意的用法

    今天在学习vue.js的render时,遇到需要重复构造多个同类型对象的问题,在这里发现原生JS中apply()方法的一个特殊的用法: var ary = Array.apply(null, { &q ...

  5. js中apply方法的使用

    js中apply方法的使用   1.对象的继承,一般的做法是复制:Object.extend prototype.js的实现方式是: Object.extend = function(destinat ...

  6. javascript中apply、call和bind的区别,容量理解,值得转!

    a)  javascript中apply.call和bind的区别:http://www.cnblogs.com/cosiray/p/4512969.html b)  深入浅出 妙用Javascrip ...

  7. 关于js中for in和foreach in的区别

    js 中for in 和foreach in的区别 两个的作用都用来遍历对象,但为什么有了for in语句了还要foreach in语句呢,后来看了下foreach in开发的文档,foreach i ...

  8. js中加“var”和不加“var”的区别

    JavaScript 拥有动态类型.这意味着相同的变量可用作不同的类型: var x // x 为 undefined var x = 6; // x 为数字 var x = "Bill&q ...

  9. C#中??和?分别是什么意思? 在ASP.NET开发中一些单词的标准缩写 C#SESSION丢失问题的解决办法 在C#中INTERFACE与ABSTRACT CLASS的区别 SQL命令语句小技巧 JQUERY判断CHECKBOX是否选中三种方法 JS中!=、==、!==、===的用法和区别 在对象比较中,对象相等和对象一致分别指的是什么?

    C#中??和?分别是什么意思? 在C#中??和?分别是什么意思? 1. 可空类型修饰符(?):引用类型可以使用空引用表示一个不存在的值,而值类型通常不能表示为空.例如:string str=null; ...

随机推荐

  1. thinkphp一键清除缓存的方法

    后台控制器: <?php namespace Home\Controller; use Think\Controller; class HuancuController extends Cont ...

  2. transient在java中的作用

    java 的transient关键字的作用是需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中. trans ...

  3. a标签 href触发及传值

    var d=document.getElementById("exportA");alert(d.href);d.href="${ctx}/templet/tEdasTe ...

  4. Java 10的10个新特性,将彻底改变你写代码的方式!

    Java 9才发布几个月,很多玩意都没整明白,现在Java 10又快要来了.. 这时候我真尼玛想说:线上用的JDK 7 甚至JDK 6,JDK 8 还没用熟,JDK 9 才发布不久不知道啥玩意,JDK ...

  5. 使用APOC技术从MYSQL数据库导数据到Neo4j图数据库(JDBC)

                                                     Neo4j 数据导入 一.安装与部署Neo4j 直接在官网下载安装包安装,解压即可. 2.mysql ...

  6. mysql初次使用

  7. 开机自动调用.bat文件且浏览器全屏展示

    1,将 .bat文件放入到以下路径中 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup 或 C:\Users\Administr ...

  8. day1-字符串、列表

    字符串操作: name = "Wills Qian" # 创建字符串变量 print(len(name)) # 打印字符串长度 print(name[0]) # 提取第一个字符W ...

  9. Oracle使用语句块之循环插入数据

    1.业务要求:  将oracle表A的整表的数据一次性导入到表B中 , 以A_ID为外键关联. (*******如果开发环境和实际生产环境的数据一致,而且数据量比较小情况,可以直接手动添加数据; ** ...

  10. C++萃取技术的一个简单初探

    首先本文并不是讲解C++萃取技术,关于C++的萃取技术网上有很多文章,推荐http://www.cppblog.com/woaidongmao/archive/2008/11/09/66387.htm ...