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; ...
随机推荐
- 实现客户端连接Mysql数据库服务器
以前学习mysql的时候,都是部署在本机,这样不存在客户端主机与服务器主机连接的问题,都是直接用localhost登录就行. 今天因项目需要,我们把mysql部署在服务器上,然后客户端装了client ...
- fatal error U1087: cannot have : and :: dependents for same target Stop.
转自VC错误:http://www.vcerror.com/?p=72 问题描述: 完成后编译,发现有错误 D:\WinDDK\7600.16385.1\bin\makefile.new(7117) ...
- VC6 Release下,生成pdb文件
1.Generate debug必须选上,否则没有调试信息 2.把优化disable,否则容易产生代码地址偏移: 3.用program database产生PDB文件: 4.将dll, exe, pd ...
- python元组与字典
一.元组 1.元组的表达 (1,2,3,4) ('olive',123) ("python",) 创建元组: a=tuple((1,2,3,)) b=("python&q ...
- <scrapy爬虫>基本操作
scrapy选择器的用法 //selector可以加可以不加 response.selector.xpath("//title/text()").extract_first() r ...
- 激活office2016的心路历程
先转换成VOL版本 32位的office2016用如下代码 @echo off :ADMIN openfiles >nul >nul ||( echo Set UAC = CreateOb ...
- WPF 字体描边的实现方式
原文:WPF 字体描边的实现方式 <local:TextPath x:Name="PathEdge" Fill="Red" Stroke=" ...
- selenium基础(控制浏览器)
python基础(控制浏览器) 控制浏览器 控制浏览器窗口大小 设置浏览器屏幕大小方法:set_window_size() 浏览器最大化:maximize_window() 浏览器最小化:minimi ...
- iOS逆向系列-theos
概述 theos是GitHub开源的一个项目,通过nic.pl创建tweak项目.通过编写我们注入代码,然后执行编译.打包.安装等操作将代码注入iPhone安装的制定程序. theos环境配置 安装签 ...
- 【笔记篇】C#笔记1
返回目录:目录请戳这里~ 以后的C#笔记如果不出意外的话都是Win10 Professional + VS2015 Professional出的,(当然还有直接在编译框敲的所以能不能过编译我也不知道┑ ...