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; ...
随机推荐
- 基于UDP协议的套接字编程
基于udp协议的套接字编程 UDP是无链接的,先启动那一端都不会报错 UDP协议是数据报协议,发空的时候也会自带报头,因此客户端输入空,服务端也能收到 一般不用与传输大数据 虽然没有粘包问题,但是不能 ...
- Django2.0+小程序技术打造微信小程序助手✍✍✍
Django2.0+小程序技术打造微信小程序助手 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题 ...
- vue 利用intersectionOberver实现全局appear/disappear事件
搬运自:https://juejin.im/post/5cd10959f265da03a00fe5c6 效果: demo地址: https://codepen.io/deepkolos/pen/OYP ...
- 2019-9-23-asp-dotnet-core-3.0-接口返回-json-使用-PascalCase-格式
title author date CreateTime categories asp dotnet core 3.0 接口返回 json 使用 PascalCase 格式 lindexi 2019- ...
- LINUX用户和用户组操作命令
Id Finger Pwck 检查/etc/passwd配置文件内的信息与实际主文件夹是否存在,还可比较/etc/passwd和/etc/shadow的信息是否一致,另外如果/etc/passwd中的 ...
- 今天给各位介绍Linux touch命令详述
触摸命令 touch命令有两个功能:一个是将现有文件的时间戳更新为系统的当前时间(默认模式),它们的数据将保持不变;第二个是创建一个新的空文件. 语法 触摸(可选) 最常见的用法:touch file ...
- HAVING方法也是连贯操作之一
HAVING方法也是连贯操作之一,用于配合group方法完成从分组的结果中筛选(通常是聚合条件)数据. having方法只有一个参数,并且只能使用字符串,例如: $this->field('us ...
- &卡特兰数学习笔记
一.关于卡特兰数 卡特兰数是一种经典的组合数,经常出现在各种计算中,其前几项为 : 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 20801 ...
- 线性dp——cf1032
升维来保存第i位按j是否可行,然后枚举i-1个的状态,用5*5n就可以完成递推 /* dp[i][j]==0表示第i步按j不可行 */ #include<bits/stdc++.h> us ...
- 项目接入即时聊天客服系统(环信系统)PHP后端操作
环信工作原理: 一.由于环信没有直接的接口来主动调取本项目中的用户数据,所有用户信息必须在环信服务器上注册对应信息成为环信的用户:(这样才能当用户进入聊天时显示其基本信息,如:名称.昵称.电话.邮箱等 ...