在javascript中一共有四种调用模式:方法调用模式、函数调用模式、构造器调用模式和apply调用模式。这些模式在如何初始化关键参数this上存在差异

方法调用模式
当一个函数被保存为对象的一个属性时,我们称之它为该对象的一个方法,那么this被绑定到该对象上。
复制代码 代码如下:
var myObject={
name : "myObject" ,
value : 0 ,
increment : function(num){
this.value += typeof num === 'number' ? num : 0;
} ,
toString : function(){
return '[Object:'+this.name+' {value:'+this.value+'}]';
}
}
alert(myObject);//[Object:myObject {value:0}]

函数调用模式
当一个函数并非一个对象的函数时,那么它被当作一个函数来调用,this被绑定到全局对象上。这是语言设计的一个错误。倘若语言设计正确,当内部函数调用时,this应该仍然绑定到外部函数的this变量上。如:
复制代码 代码如下:
var myObject={
name : "myObject" ,
value : 0 ,
increment : function(num){
this.value += typeof(num) === 'number' ? num : 0;
} ,
toString : function(){
return '[Object:'+this.name+' {value:'+this.value+'}]';
},
getInfo:function(){
return (function(){
return this.toString();//内部匿名函数中this指向了全局对象window
})();
}
}
alert(myObject.getInfo());//[object Window]

当幸运的是,有一个很容易的解决方案:定义一个变量并给它赋值为this,那么内部函数通过该变量访问到指向该对象的this,如:
复制代码 代码如下:
var myObject={
name : "myObject" ,
value : 0 ,
increment : function(num){
this.value += typeof num === 'number' ? num : 0;
} ,
toString : function(){
return '[Object:'+this.name+' {value:'+this.value+'}]';
},
getInfo:function(){
var self=this;
return (function(){
return self.toString();//通过变量self指向myObject对象 ~~~在该匿名函数体内this指向全局对象
})();
}
}
alert(myObject.getInfo());//[Object:myObject {value:0}]

构造器调用模式
JavaScript是一门基于原型继承的语言。这意味着对象可以直接从其他对象继承属性。该语言是无类别的。
如果一个函数前面带上new来调用,那么将创建一个隐藏连接到该函数的prototype成员的新对象,同时this将会被绑定到构造函数的实例上。
复制代码 代码如下:
function MyObject(name){
this.name=name || 'MyObject';
this.value=0;
this.increment=function(num){
this.value += typeof num === 'number' ? num : 0;
};
this.toString=function(){
return '[Object:'+this.name+' {value:'+this.value+'}]';
}
this.target=this;
}
MyObject.prototype.getInfo=function(){
return this.toString();
}
/*
同时创建一个MyObject.prototype对象,实例myObject继承了MyObject.prototype的所有的属性,
this绑定到了MyObject的实例上
*/
var myObject=new MyObject();
var otherObject=new MyObject();
//alert(myObject.target===myObject);//ture
//alert(myObject.target.getInfo());//[Object:MyObject {value:0}]
myObject.increment(10);
otherObject.increment(20);
alert(myObject.value);//10
alert(otherObject.value);//20

Apply 调用模式
JavaScript是一门函数式的面向对象编程语言,所以函数可以拥有方法。
函数的apply方法,如同该对象拥有此方法,使该对象拥有此方法。此时this指向该对象。
apply接收两个参数,第一个是要绑定的对象(this指向的对象),第二个是参数数组.
复制代码 代码如下:
function MyObject(name){
this.name=name || 'MyObject';
this.value=0;
this.increment=function(num){
this.value += typeof(num) === 'number' ? num : 0;
};
this.toString=function(){
return '[Object:'+this.name+' {value:'+this.value+'}]';
}
this.target=this;
}
function getInfo(){
return this.toString();
}
var myObj=new MyObject();
alert(getInfo.apply(myObj));//[Object:MyObject {value:0}],this指向myObj
alert(getInfo.apply(window));//[object Window],this指向window

js函数调用模式总结的更多相关文章

  1. js函数调用模式

    1.函数调用 调用一个函数将暂停当前函数的执行,传递控制权和参数给新函数.除了函数声明时定义的形参,每个函数还接受两个附加的参数:this和arguments(arguments并不是一个真正的数组, ...

  2. JS函数调用的方法

    JS函数调用的四种方法:方法调用模式,函数调用模式,构造器调用模式,apply,call调用模式 1.方法调用模式:先定义一个对象,然后在对象的属性中定义方法,通过myobject.property来 ...

  3. JS调用模式

    在js中,一共4中调用方式.需要注意的是,调用方式中,this的指向问题. 函数调用模式 this丢失,debug会提示未定义相应属性.按照规范,需要将this赋值给that let myObj = ...

  4. JS函数调用的四种方法

    js的函数调用会免费奉送两个而外的参数就是 this 和 arguments .arguments是参数组,他并不是一个真实的数组,但是可以使用.length方法获得长度. 书上有说4中调用方式: 方 ...

  5. js函数调用的几种方法

    js的函数调用会免费奉送两个而外的参数就是 this 和 arguments .arguments是参数组,他并不是一个真实的数组,但是可以使用.length方法获得长度. 书上有说4中调用方式: 方 ...

  6. js严格模式“use strict”

    js的严格模式会放弃js中的一些不正规的写法,参考 http://www.cnblogs.com/God-Shell/p/3139329.html: 使用声明"use  strict&quo ...

  7. JS 函数调用

    Js函数调用的方式有如下几种情况: (1)具名函数直接调用 function foo() { } foo(); (2)匿名函数通过引用来调用 fooRef = function() { } fooRe ...

  8. JavaScript 方法调用模式和函数调用模式

    这两天在读<JavaScript语言精粹>关于第4章函数调用的几种模式琢磨了半天. 这里就说一下方法调用模式跟函数调用模式. 方法调用模式: 当一个函数被保存为对象的一个属性时,我们称它为 ...

  9. js调试模式控制台输出信息

    js调试模式控制台输出信息.console.log

随机推荐

  1. JavaScript之ClassName属性学习

    在前面的style属性学习中,知道了通过style属性可以控制元素的样式,从而实现了行为层通过DOM的style属性去干预变现层显示的目地,但是这种就是不好的,而且为了实现通过DOM脚本设置的样式,你 ...

  2. javaWeb项目带红色感叹号问题原因

    自建Userlibrary 中库中含有非.jar 文件.

  3. Log4net 自定义字段到数据库

    今天要求做个log4net自定义字段到数据库,在网上找了好多例子,都运行不成功.最后找了个国外的,很简单的就解决了. log4net它已经定义的字段有 <commandText value=&q ...

  4. OSCache缓存框架介绍

          OSCache是一种开放性的JSP定制标记应用,由OpenSymphony设计,提供了在现有JSP页面之内实现快速内存缓冲的功能. OSCache是个一个广泛采用的高性能的J2EE缓存框架 ...

  5. iOS 使用xib创建cell的两种初始化方式

    曾几何时,被自己坑过,为了防止下次继续被自己坑,我决定了!在每个我能看到的地方,都把问题写一遍!!! 方法一: ? 1 2 3 4 第一步: [self.collectionView register ...

  6. CoreText 简单 使用

    - (void)drawRect:(CGRect)rect { NSString *longText = @"CoreText"; /* ... */ NSRange rang = ...

  7. 一起来看看css中的单位

    一起来看看css中的单位 由于一直以来对于css中的百分比单位究竟是相对于谁的比例,这个问题不是很了解,所以就专门找资料看了一下. <div class="container w500 ...

  8. 如何使用Palette提取Bitmap的颜色

    5.X提出了color palette 的概念,能够让主题动态的去适应当前的页面色调,让整个app色调看起来比较和谐统一 那么如何使用Palette呢,必不可少,我们需要在Android studio ...

  9. HttpWebRequest使用注意(发生阻塞的解决办法)

    原文 http://www.cnblogs.com/Fooo/archive/2008/10/31/1323400.html HttpWebRequest使用注意(发生阻塞的解决办法) , count ...

  10. 基于纯Java代码的Spring容器和Web容器零配置的思考和实现(3) - 使用配置

    经过<基于纯Java代码的Spring容器和Web容器零配置的思考和实现(1) - 数据源与事务管理>和<基于纯Java代码的Spring容器和Web容器零配置的思考和实现(2) - ...