apply call this arguments caller callee
JavaScript为函数对象定义了两个方法:apply和call,它们的作用都是将函数绑定到另
外一个对象上去运行,两者仅在定义参数的方式有所区别:
Function.prototype.apply(thisArg,argArray); Function.prototype.call(thisArg[,arg1[,arg2…]]);
从函数原型可以看到,第一个参数都被取名为thisArg,也就是说,所有函数内部的this
指针都会被赋值为thisArg,这就达到了将函数作为另外一个对象的方法运行的目的。两个
方法除了thisArg 参数,都是为Function 对象传递的参数。
<script type="text/javascript">//定义一个函数func1,具有属性p和方法A function func1() {this.p = "func1-";this.A = function (arg) {alert(this.p + arg);}}//定义一个函数func2,具有属性p和方法B function func2() {this.p = "func2-";this.B = function (arg) {alert(this.p + arg);}}var obj1 = new func1();var obj2 = new func2();obj1.A("byA"); //显示func1-byAobj2.B("byB"); //显示func2-byBobj1.A.apply(obj2, ["byA"]); //显示func2-byA,其中[“byA”]是仅有一个元素的数组,下同obj2.B.apply(obj1, ["byB"]); //显示func1-byBobj1.A.call(obj2, "byA"); //显示func2-byAobj2.B.call(obj1, "byB"); //显示func1-byB</script>
可以看出,obj1的方法A被绑定到obj2运行后,整个函数A的运行环境就转移到了obj2,
即this指针指向了obj2。同样obj2 的函数B也可以绑定到obj1 对象去运行。代码的最后4
行显示了apply和call函数参数形式的区别。
与 arguments 的length属性不同,函数对象的还有一个参数相关的属性length,它表示
函数定义时所指定参数的个数,而非调用时实际传递的参数个数。例如下面的代码将显示2:
function sum(a,b){ return a+b; } alert(sum.length);
call,apply都是Function的原型的方法,其他function继承
this
和传统意义的面向对象的语言不同,JavaScript 中的this 指针是一个动态的变量,一个
方法内的this指针并不是始终指向定义该方法的对象的,在上一节讲函数的apply和call方
法时已经有过这样的例子。
<script type="text/javascript"><!--//创建两个空对象var obj1 = new Object();var obj2 = new Object();//给两个对象都添加属性p,并分别等于1和2obj1.p = 1;obj2.p = 2;//给obj1添加方法,用于显示p的值obj1.getP = function () {alert(this.p); //表面上this指针指向的是obj1 }//调用obj1的getP方法 obj1.getP();//使obj2的getP方法等于obj1的getP方法obj2.getP = obj1.getP;//调用obj2的getP方法 obj2.getP(); //--></script>
从代码的执行结果看,分别弹出对话框1 和2。由此可见,getP函数仅定义了一次,在
不同的场合运行,显示了不同的运行结果,这是有this指针的变化所决定的。在obj1 的getP
方法中,this就指向了obj1 对象,而在obj2 的getP 方法中,this就指向了obj2 对象,并通
过this指针引用到了两个对象都具有的属性p。
由此可见,JavaScript 中的this 指针是一个动态变化的变量,它表明了当前运行该函数
的对象。由this指针的性质,也可以更好的理解JavaScript中对象的本质:一个对象就是由
一个或多个属性(方法)组成的集合。每个集合元素不是仅能属于一个集合,而是可以动态
的属于多个集合。这样,一个方法(集合元素)由谁调用,this指针就指向谁。实际上,前
面介绍的apply方法和call方法都是通过强制改变this指针的值来实现的,使this指针指向
参数所指定的对象,从而达到将一个对象的方法作为另一个对象的方法运行的效果。
this的范围
var user={ name:"jack", //定义了name属性,初始化为jack favoriteColor:["red","green","black","white"],//定义了颜色喜好数组 hello:function(){ //定义了方法hello alert("hello,"+this.name); }, sex:"male" //定义了性别属性sex,初始化为sex } user.hello(); //"hello,jack"
var user={ name:"jack", //定义了name属性,初始化为jack favoriteColor:["red","green","black","white"],//定义了颜色喜好数组 hello:function(){ //定义了方法hello alert("hello,"+name); }, sex:"male" //定义了性别属性sex,初始化为sex } user.hello(); //"hello,"
name="hongda"; var user={ name:"jack", //定义了name属性,初始化为jack favoriteColor:["red","green","black","white"],//定义了颜色喜好数组 hello:function(){ //定义了方法hello alert("hello,"+name); }, sex:"male" //定义了性别属性sex,初始化为sex } user.hello(); //"hello,hongda"
name = "hongda";var user = {name: "jack", //定义了name属性,初始化为jackfavoriteColor: ["red", "green", "black", "white"], //定义了颜色喜好数组hello: function () { //定义了方法helloname = "hongdadada";alert("hello," + name);},sex: "male" //定义了性别属性sex,初始化为sex }user.hello(); //"hello,hongdadada"
一个对象内部的方法调用该对象的属性时要指明this,该属性不是某个范围内的变量。
function fun() {name = "hongdada";function show() { //没有意义alert(name);}}var f = new fun();console.dir(f);
function fun() {this.name = "hongdada";this.show=function show() {alert(name);}}var f = new fun();console.dir(f);
function中没有this时,它就是个方法,只有有this时它才类似一个类
传递给函数的隐含参数:arguments
当进行函数调用时,除了指定的参数外,还创建一个隐含的对象——arguments。
arguments是一个类似数组但不是数组的对象,说它类似是因为它具有数组一样的访问性质,
可以用arguments[index]这样的语法取值,拥有数组长度属性length。arguments 对象存储的
是实际传递给函数的参数,而不只局限于函数声明所定义的参数列表,
function func(a,b){ alert(a); alert(b); for(var i=0;i<arguments.length;i++){ alert(arguments[i]); } } func(1,2,3); //1,2,1,2,3
代码:
<script type="text/javascript">function dwn(s) {document.write(s + "<br/>");}//定义一个多边形(Polygon)类型 function Polygon() {//存放多边形的顶点var m_points = [];m_points = Array.apply(m_points, arguments);//用上面介绍的那种方式定义getter function GETTER() { };GETTER.prototype = m_points[0];this.firstPoint = new GETTER();//公有属性this.length = {valueOf: function () { return m_points.length },toString: function () { return m_points.length }}//添加一个或多个顶点this.add = function () {m_points.push.apply(m_points, arguments);}//取得序号为idx 的顶点this.getPoint = function (idx) {return m_points[idx];}//设置特定需要的顶点this.setPoint = function (idx, point) {if (m_points[idx] == null) {m_points[idx] = point;}else {m_points[idx].x = point.x;m_points[idx].y = point.y;}}}//构造一个三角形pvar p = new Polygon({ x: 1, y: 2 }, { x: 2, y: 4 }, { x: 2, y: 6 });dwn(p.length); //3dwn(p.firstPoint.x); //1dwn(p.firstPoint.y); //2p.firstPoint.x = 100; //不小心写了它的值dwn(p.getPoint(0).x); //1 不会影响到实际的私有成员delete p.firstPoint.x; //恢复dwn(p.firstPoint.x); //1p.setPoint(0, { x: 3, y: 4 }); //通过setter 改写了实际的私有成员dwn(p.firstPoint.x); //3 getter 的值发生了改变dwn(p.getPoint(0).x); //3</script>
应用例子:
function dwn(s) {document.write(s + "<br/>");}function App() {var fun={};var arr = Array.apply(null, arguments);var arr2 = Array.apply(arr2, arguments);var arr3 = Array.apply(fun, arguments);var arr4 = Array.apply(window, arguments);dwn(arr);dwn(arr2);dwn(arr3);dwn(arr4);}App(1, 2, 3, 4, 5, 6, 7, 8);
Array这个function方法对象初始化中没有使用this,所有thisArg不管填什么都没影响。
function Class1() {this.name = "class1";this.showNam = function () {alert(this.name);}}function Class2() {this.name = "class2";}var c1 = new Class1();var c2 = new Class2();c1.showNam.call(c2); //class2
call也可以形成继承
function Class1() {this.showTxt = function (txt) {alert(txt);}}function Class2() {Class1.call(this);}var c2 = new Class2();c2.showTxt("cc"); //cc
class2继承class1
多继承
function Class1() {this.showTxt1 = function (txt) {alert("Class1:"+txt);}}function Class0() {this.showTxt0 = function (txt) {alert("Class0:"+txt);}}function Class2() {Class0.call(this);Class1.call(this);}var c2 = new Class2();c2.showTxt0("cc");c2.showTxt1("cccc");
在javascript框架prototype里就使用apply来创建一个定义类的模式
var Class = {create: function() {return function() {this.initialize.apply(this, arguments);}} }
解析:从代码看,该对象仅包含一个方法:Create,其返回一个函数,即类。但这也同时是类的
构造函数,其中调用initialize,而这个方法是在类创建时定义的初始化函数。通过如此途径,
就可以实现prototype中的类创建模式
var vehicle=Class.create();vehicle.prototype = {initialize: function (type) {this.type = type;},showSelf: function () {alert("this vehicle is " + this.type);}}var moto=new vehicle("Moto"); moto.showSelf();
apply call this arguments caller callee相关推荐
- javascript下的arguments,caller,callee,call,apply示例及理解
在看到大家如此关注JS里头的这几个对象,我试着把原文再修改一下,力求能再详细的阐明个中意义.在提到上述的概念之 前,首先想说说javascript中函数的隐含参数:arguments Argument ...
- JS报错-Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on...
报错信息:Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on stric ...
- js中函数参数arguments、callee、caller,值传递、重载
全栈工程师开发手册 (作者:栾鹏) js系列教程4-函数.函数参数教程全解 函数参数 arguments javascript中的函数定义并未指定函数形参的类型,函数调用也未对传入的实参值做任何类型检 ...
- 【转载】全面理解javascript的caller,callee,call,apply概念(修改版)
今天写PPlayer,发现有段代码引起了我的兴趣: var Class = { create: function() { return function() { this.initialize.app ...
- js理解 call( ) | apply( ) | caller( ) | callee( )
被js的这几个方法搞的this晕头转向,下定决心搞清楚: 1.call( )和apply( ):两者都可以将函数绑定到另外一个对象上去运行,只是参数的传递方式不同,两者都可以使当前函数拥有另一个对象的 ...
- js apply/call/caller/callee/bind使用方法与区别分析
一.call 方法 调用一个对象的一个方法,以另一个对象替换当前对象(其实就是更改对象的内部指针,即改变对象的this指向的内容). Js代码 call([thisObj[,arg1[, arg2[, ...
- arguments,callee,caller
arguments 定义函数时没有定义参数 如果实参数量大于形参时,使用arguments arguments只能出现在函数语句块中,不需要定义,直接使用. 用于当前函数的参数不固定数量. funct ...
- 关于arguments,caller以及匿名函数调用的问题
此文内容不深,就当一个简单的笔记或总结吧. 先从arguments对象说起吧,[fnName.]arguments (其中fnName可选),为当前执行的 function 对象返回一个argumen ...
- javaScript(call,apply,date,arguments,Math)
目录 call和apply this的情况 arguments Date对象 Math 包装类 字符串的相关方法 正则表达式 使用字面量来创建正则表达式 字符串和正则相关的方法 量词 练习 call和 ...
最新文章
- 1.mongodb在centos上面安装
- numpy.squeeze() 去除维度为1的向量
- 斯坦福CS231 BP后向传播
- Leetcode题目:House Robber II
- python 代理使用方法简介
- shell之实战应用一(查找xml文档中的关键字段)
- Error running ‘xxx‘: Command line is too long. Shorten command line for xxx or also for Spring Boot
- 官网安装Nvidia CUDA Toolkit、cuDNN报错502的备用镜像下载网址
- C++中的数组与指针
- 【Elasticsearch】Elasticsearch 5.1.2滚动升级至 5.6.4
- SQL Server超时诊断和调优
- 在Ubuntu上使用apt-get安装MySQL+安全优化
- 18.Linux软件安装之Rpm安装
- 《CSS世界》(张鑫旭)pdf
- 什么是TCP粘包?怎么解决TCP粘包问题?
- 嵌入式开发Linux入门
- 教程篇(7.0) 03. FortiGate安全 防火墙策略 ❀ Fortinet 网络安全专家 NSE 4
- python之代码可读性浅谈
- 云端IDE:阿里云机器学习与PAI-DSW | 《阿里云机器学习PAI-DSW入门指南》
- 编写一个简单的javaweb网上商城项目