http://blog.sina.com.cn/s/blog_621f1e120100rj21.html

this 在 JavaScript 开发中占有相当重要的地位,不过很多人对this这个东西都感觉到琢磨不透。要真正理解JavaScript的函数机制,就非常有必要搞清楚this到底是怎么回事。

函数调用方式不同,this 含义也跟着不同。JavaScript语言中有七种调用函数方式:
 
第一种:调用方法
var obj = {
    method: function() { alert(this === obj); }
}
obj.method();
上面这行obj.method()显然method是作为方法被调用,这种情况下,函数体中的this绑定的就是method的宿主对象,也就是obj。
从这种调用方式我们得出第一定律:
第一定律:以方法方式调用函数,this则绑定宿主对象。

第二种:调用全局函数
var method = function(){alert(this === window);}
method();
上面这个函数是个全局函数。我们知道,全局变量或函数都相当于window对象的属性。也就是说,上面这句实际上等同于下面这句:
window.method = function(){alert(this === window);}
window.method();
既然这样,那么这里 this 绑定到 window 对象就显而易见,很容易理解了。相当于方法调用模式的一个特例,并不违背第一定律。

第三种:全局函数内调用内部函数

var m_ext = function() {
    alert(this === window);
    var m_inner = function() {
        alert(this === window);
    }
    m_inner();
}
m_ext();
执行上面这段代码,你会惊讶的发现,两个布尔表达式的值都是真。也就是说子函数孙函数,只要是以函数的方式调用,this 就铁了心绑定 window 对象了。从这种调用方式我们得出第二定律:
第二定律:不论子函数孙函数,只要是以函数的方式调用,this 就铁了心绑定 window 对象。

第四种:方法内调用内部函数

var obj = {};
obj.method = function() {
    alert(this === obj);
    var m_inner = function() {
        alert(this === window);
    }
    m_inner();
}
obj.method();
执行上面这段代码,第一个this绑定到obj你不奇怪,第二个this绑定到window其实也不奇怪。它仍然遵守第二定律,也就是不论子函数孙函数,只要是以函数的方式调用,this 就铁了心绑定 window 对象。

第五种:作为构造函数调用

function Person(name, age){
    this.name = name;
    this.age = age;
}
var john = new Person('John', 38);
alert(JSON.stringify(john));
你会说,哇,这很眼熟。生成某个类的新对象啊。Javascript就是这么另类,函数确实可以这么调。
这次弹出的是这样一个字符串:{"name":"John","age":38}。哇,这次我明明没在函数定义里写return 语句,它却主动返回了一个对象给我。没错,即便你在函数定义里return某个东西,它也不会理你。(注意:如果你return一个function就会有惊喜,不信你试试看)。从这种调用方式我们得出第三定律:
第三定律:如果在一个函数本身没有返回值,在其前面加上 new 调用,就会创建一个连接到该函数 prototype 属性的新对象,再把 this 绑定到该对象,然后执行该函数,最后返回该对象。如果该函数有返回值,且返回值为字符串/数字/布尔值等简单对象的话,该返回值会被丢弃。但如果该函数的返回值为对象,函数或者数组等复杂对象的话,该函数则会返回该返回值,抛弃this绑定的对象。据我测试,如果返回值是一个函数时,该函数会返回undefined。我暂时还不知道为什么会这样。

第六种:用函数对象的apply方法调用

var my_concat = function(stra, strb){
    alert(this);
    return stra + '' + strb;
}
var param = ['hello', ' world']
alert(my_concat.apply('bullshit', param));

你一定注意了,在这里 this 绑定的是apply方法的第一个参数 'bullshit'。从这里我们得出第四定律:
第四定律:用方法的apply/call方法调用方法时,this 则被绑定到apply/call方法的第一个参数。
想谁就是谁,嗯,吴妈也行。JavaScript的程序员们好幸福哦。

第七种:用函数对象的call方法调用
var my_concat = function(stra, strb){
    alert(this);
    return stra + '' + strb;
}
alert(my_concat.call('bullshit', 'hello',' world'));

对啦,你或许会多问一句,apply 的第二个参数有什么规定?call方法和apply又有什么不同?嗯 ,真是勤学好问,我就再啰嗦一下说说apply和call:

apply 和 call 的区别:

apply要求第二个参数必须是数组。否则就会报 TypeError: second argument to Function.prototype.apply must be an array. 而call则没这么严格啦,第二个参数要什么类型?随意啦,还可以有第三个第四个第五个第六个....啦。

我想我说的够清楚了。感谢《JavaScript The Good Parts》和《JavaScript Definitive Guide》,要不然我也弄不明白呢!

转载于:https://www.cnblogs.com/tarrying/p/4345493.html

JavaScript中七种函数调用方式及对应 this 的含义相关推荐

  1. Javascript中四种函数调用方式

    为了解释方便,先创建一个函数: function showmsg(){ console.log(this);} 它的作用是打印this这个对象,也方便我们了解它到底指代什么. 一.直接调用 showm ...

  2. javascript 的七种继承方式(三)组合继承

    组合继承 前面两篇我们了解到:原型链继承存在着引用类型问题,而借用构造函数又无法实现函数复用和原型方法继承的问题.那么能不能把两者结合一下,取其精华,弃其糟粕?答案是肯定的.那就是接下来我们要介绍的组 ...

  3. JavaScript中6种继承方式总结

  4. JavaScript中四种不同的属性检测方式比较

    JavaScript中四种不同的属性检测方式比较 1. 用in方法 var o = {x:1}; "x" in o; //true "y" in o; //fa ...

  5. 算法中七种常见的时间复杂度

    这是我的推广信息,以激励自己更好的分享自己的知识和经验!也希望看到的你能够多多支持,谢谢! 1. 滴滴云AI大师: 目前滴滴云正在大力推广自己的云计算服务,需要购买的朋友们用我的AI大师码 「2049 ...

  6. 【数据库视频】七种连接方式

    数据表的查询与管理只是针对数据库中的一个表格进行的查询管理,如果现在我们想要同时的看到两个数据表中的数据的或,需要怎么实现?答案是:使用多连接的方式进行查询 标题中说了SQL中有七种连接的方式,那么具 ...

  7. apache php 工作模式,PHP Apache中两种工作方式区别(CGI模式、Apache 模块DLL)

    搜索热词 对PHP在Apache中两种工作方式的区别(CGI模式.Apache 模块DLL)感兴趣的小伙伴,下面一起跟随编程之家 jb51.cc的小编两巴掌来看看吧! Windows 下有两种方法使 ...

  8. .NetCore中三种注入方式的思考

    .NetCore中三种注入方式的思考 原文:.NetCore中三种注入方式的思考 该篇内容由个人博客点击跳转同步更新!转载请注明出处! .NetCore彻底诠释了"万物皆可注入"这 ...

  9. C语言中几种输入方式

    当我们输入一串字符或者数字时,需要一种标志作为输入结束的标志,所以我总结了以下几种: 1.输入一串字符串以回车键作为输入结束的标志 char ch; while(((ch=getchar())!='n ...

最新文章

  1. 前嗅ForeSpider教程:如何创建新任务
  2. weblogic清除缓存
  3. seaborn分类数据可视:散点图|箱型图|小提琴图|lv图|柱状图|折线图
  4. css flex布局 模型(CSS justify-content 属性) - 代码案例
  5. FastStoneCapture屏幕截图软件
  6. PayPal旗下Venmo:允许信用卡用户将现金返还转换为加密币
  7. 图论最短路及生成树(Prim,Djikstra,Spfa,Bellan-ford,kruskal,topsort)
  8. 细胞亚器文献阅读之酵母液泡与线粒体的动态互作A Dynamic Interface between Vacuoles and Mitochondria in Yeast
  9. 剑指:合并两个排序的链表
  10. 获取图像像素点的概率分布图
  11. Redis中Pipeline的使用
  12. 英尺英寸和厘米的换算_中国的尺和厘米的换算,英尺英寸和厘米换算
  13. Git(码云)如何把本地仓库提交到远程仓库
  14. LCD显示屏的器件选择和驱动电路设计
  15. Mac 下pyppeteer下载Chromium慢 / pyppeteer下载慢 / Chromium下载慢 / Chromium下载地址
  16. 安全检查计算机,计算机可以通过安全检查机吗?
  17. 2021-泛微OA V8 SQL注入漏洞
  18. 常用数据库URL地址的写法
  19. E.03.08. Scrapped Plans for London Concert Hall Sour Mood for U.K. Musicians
  20. 涛思数据库(二)——上手使用

热门文章

  1. 台式机安装系统时区分BIOS与UEFI
  2. Python3高并发定时更新任务进程池和线程池的使用
  3. DS1302示例子程序
  4. springboot拦截器拦截提示_Springboot拦截器使用及其底层源码剖析
  5. 计算机学院的运动会介绍,敢于拼搏 超越自我 --计算机学院校运动会动员大会召开...
  6. cygwin编译verilator_Sublime text3 + Verilator 实现自动语法检错
  7. matlab检测图片马赛克,python 检测图片是否有马赛克
  8. 第一章 Oracle 11g 数据库——在Windows 上安装部署
  9. python003 一 Python起步、pyhthon运行方式、语法结构、python变量
  10. Nginx实现静态代理,负载均衡,前后端分离