JS中apply和call的联系和区别
以下内容翻译自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的联系和区别的更多相关文章
- [转]JS中apply和call的联系和区别
JS中有时常用到 apply 和 call 两个方法,搜索网上很多,整理如下,简单看看这两个联系和区别, 联系: 网上查到关于apply和call的定义:这两个方法都能劫持另外一个对象的方法,继承另外 ...
- JS中apply与call的含义与区别
JavaScript中,apply()与call()的含义一样,均为改变调用函数中的this指向.其中apply()与call()的第一个参数表示所要指向的对象,若调用函数无参数可不写,则默认为win ...
- JS中apply和call的应用和区别
因为object没有某个方法,但是别的对象有,可以借助apply或call像别的对象借方法来操作. 猫吃鱼,狗吃肉,奥特曼打小怪兽. 有天狗想吃鱼了 猫.吃鱼.call(狗,鱼) 狗就吃到鱼了 猫成精 ...
- 原生JS中apply()方法的一个值得注意的用法
今天在学习vue.js的render时,遇到需要重复构造多个同类型对象的问题,在这里发现原生JS中apply()方法的一个特殊的用法: var ary = Array.apply(null, { &q ...
- js中apply方法的使用
js中apply方法的使用 1.对象的继承,一般的做法是复制:Object.extend prototype.js的实现方式是: Object.extend = function(destinat ...
- javascript中apply、call和bind的区别,容量理解,值得转!
a) javascript中apply.call和bind的区别:http://www.cnblogs.com/cosiray/p/4512969.html b) 深入浅出 妙用Javascrip ...
- 关于js中for in和foreach in的区别
js 中for in 和foreach in的区别 两个的作用都用来遍历对象,但为什么有了for in语句了还要foreach in语句呢,后来看了下foreach in开发的文档,foreach i ...
- js中加“var”和不加“var”的区别
JavaScript 拥有动态类型.这意味着相同的变量可用作不同的类型: var x // x 为 undefined var x = 6; // x 为数字 var x = "Bill&q ...
- C#中??和?分别是什么意思? 在ASP.NET开发中一些单词的标准缩写 C#SESSION丢失问题的解决办法 在C#中INTERFACE与ABSTRACT CLASS的区别 SQL命令语句小技巧 JQUERY判断CHECKBOX是否选中三种方法 JS中!=、==、!==、===的用法和区别 在对象比较中,对象相等和对象一致分别指的是什么?
C#中??和?分别是什么意思? 在C#中??和?分别是什么意思? 1. 可空类型修饰符(?):引用类型可以使用空引用表示一个不存在的值,而值类型通常不能表示为空.例如:string str=null; ...
随机推荐
- day 83 Vue学习四之过滤器、钩子函数、路由、全家桶等
Vue学习四之过滤器.钩子函数.路由.全家桶等 本节目录 一 vue过滤器 二 生命周期的钩子函数 三 vue的全家桶 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 Vue的过滤 ...
- vue项目的实用配置
文件压缩如何去掉console 在使用vue开发项目的过程中,免不了在调试的时候会写许多console,在控制台进行调试:在开发的时候这种输出是必须的,但是build后线上运行时这个东西是不能出现的: ...
- Gabor filter for image processing and computer vision
介绍 我们已经知道,傅里叶变换是一种信号处理中的有力工具,可以帮助我们将图像从空域转换到频域,并提取到空域上不易提取的特征.但是经过傅里叶变换后,图像在不同位置的频度特征往往混合在一起,但是Gabor ...
- select 语句中 if 的用法
IF( expr1 , expr2 , expr3 ) expr1 的值为 TRUE,则返回值为 expr2 expr1 的值为FALSE,则返回值为 expr3 例: ,); ,); ", ...
- EF Code First数据库映射规则及配置
EF Code First数据库映射规则主要包括以下方面: 1.表名及所有者映射 Data Annotation: 指定表名 1 using System.ComponentModel.DataAnn ...
- 北京服务业占GDP比重达81.7%
北京服务业占GDP比重达81.7% 2017-05-17 19:46:00 来源: 中国新闻网(北京)举报 0 易信 微信 QQ空间 微博 更多 (原标题:北京服务业占GDP比重达81.7%) ...
- Struts2OGNL
OGNL: 什么是OGNL Object Graph Navigation Language 开源项目,取代页面中Java脚本,简化数据访问 和EL同属于表达式语言,但功能更为强大 OGNL在St ...
- PKU--1267 Cash Machine(多重背包)
题目http://poj.org/problem?id=1276 分析 这是一个多重背包的问题,可以把请求的金额当作背包的重量,而货币的面值就是价值又是重量. 于是这个问题便很好理解背包了. #];; ...
- vue 监听返回
mounted: function() { //使用keep-alive时可以放在activated内 if (window.history && window.history.pus ...
- hive新加入字段插入数据需要注意事项
hive中新加字段需要注意如下 1)如果表中有分区字段,必须先删除分区才能插入数据否则为null; 2)insert override TABLE table1 select counm1,counm ...