第一部分 基础知识

第2章  this 、 call 和 apply

2.1  this

  JavaScript的 this 总是指向一个对象,而具体指向哪个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境。也就是说声明时不知道,运行时才知道。

   this 的指向大致可以分为以下 4种:

   作为对象的方法调用。

  1. <script type="text/javascript">
  2. //当函数作为对象的方法被调用时, this 指向该对象:
  3. var obj = {
  4. a:1,
  5. getA:function(){
  6. console.log(this === obj);
  7. console.log(this.a);
  8. }
  9. }
  10. obj.getA();
  11. </script>

    作为普通函数调用。

  1. <script>
  2. //作为普通函数调用
  3. window.name = 'globalName';
  4. var getName = function(){
  5. return this.name;
  6. }
  7. console.log(getName());
  8. var getId = function( id ){
  9. return document.getElementById( id );
  10. };
  11. getId( 'div1' );
  12. </script>

    构造器调用。

  1. <script>
  2. var MyClass = function(){
  3. this.name = 'sven';
  4. };
  5. var obj = new MyClass();
  6. alert ( obj.name ); // 输出:sven
  7. </script>

    Function.prototype.call 或 Function.prototype.apply 调用。

  1. <script>
  2. var obj1 = {
  3. name: 'sven',
  4. getName: function(){
  5. return this.name;
  6. }
  7. };
  8. var obj2 = {
  9. name: 'anne'
  10. };
  11. console.log( obj1.getName() ); // 输出: sven
  12. console.log( obj1.getName.call( obj2 ) ); // 输出:anne
  13. </script>

2.2  call 和 apply

  ECAMScript 3给 Function 的原型定义了两个方法,它们是 Function.prototype.call 和 Function.prototype.apply 。

2.2.1  call 和 apply 的区别

  apply 接受两个参数,第一个参数指定了函数体内 this 对象的指向,第二个参数为一个带下标的集合,这个集合可以为数组,也可以为类数组, apply 方法把这个集合中的元素作为参数传递给被调用的函数。

2.2.2  call 和 apply 的用途

  1. 改变 this 指向

  1. <script>
  2. var obj1 = {
  3. name: 'sven'
  4. };
  5. var obj2 = {
  6. name: 'anne'
  7. };
  8. window.name = 'window';
  9. var getName = function(){
  10. alert ( this.name );
  11. };
  12. getName(); // 输出: window
  13. getName.call( obj1 ); // 输出: sven
  14. getName.call( obj2 ); // 输出: anne
  15. </script>

  2.  Function.prototype.bind

  1. Function.prototype.bind = function(){
  2. var self = this,// 保存原函数
  3. context = [].shift.call(arguments);// 需要绑定的 this 上下文
  4. args = [].slice.call(arguments);// 剩余的参数转成数组
  5. // 返回一个新的函数
  6. return function(){
  7. // 执行新的函数的时候,会把之前传入的 context 当作新函数体内的 this
  8. // 并且组合两次分别传入的参数,作为新函数的参数
  9. return self.apply(context, [].concat.call(args, [].slice.call(arguments)));
  10. }
  11. }
  12.  
  13. var obj1 = {
  14. name:'john'
  15. };
  16. var func1 = function(a,b,c,d){
  17. console.log(this.name);
  18. console.log([a,b,c,d]);
  19. }.bind(obj1, 1,2);
  20.  
  21. func1(3,4);

  3. 借用其他对象的方法

    第一种场景是“借用构造函数”

  1. //借用构造函数
  2. var A = functiono(name){
  3. this.name = name;
  4. }
  5. var B = function(){
  6. A.apply(this, arguments);
  7. }
  8.  
  9. B.prototype.getName = function(){
  10. return this.name;
  11. }
  12.  
  13. var b = new B('john');
  14. console.log(b.getName());

    第二种场景借用 Array.prototype 对象上的方法

  1. //借用其它对象
  2. (function(){
  3. Array.prototype.push.call(arguments, 3);
  4. console.log(arguments);
  5. })(1,2);

第2章 this 、 call 和 apply的更多相关文章

  1. js call与apply的区别-Tom

    .apply和.call方法是在函数原型中定义的两个方法(因此所有的函数都可以访问它)允许去手动设置函数调用的this值,他们用接受 的第一个参数作为this值,this 在调用的作用域中使用.这两个 ...

  2. Angular中ngModel的$render的详解

    在我开始着手ngModel的领域时候,有一个问题很令我纠结,那就是$render()到底是做什么的呢?查了很多资料都只是简单的描述一下,这就令我很纠结了,终于在一个阳光明媚的晚上,我终于解决了这个大问 ...

  3. angularjs杂谈

    1.MVVM的看法:我给view里面各种控件也定义一个对应的数据对象,这样,只要修改这个数据对象,view里面显示的内容就自动跟着刷新,而在view里做了任何操作,这个数据对象也跟着自动更新. Vie ...

  4. 洗礼灵魂,修炼python(11)--python函数,模块

    前面的章节你如果看懂了,基本算是入门了七八了,不过如果你以为python就这么点东西,你觉得很简单啊,那你就错了,真正的东西在后面,前面我说的几大核心其实也不是多么高深多么厉害的,那些东西是基础很常用 ...

  5. 使用 for 循环

    for 循环通过迭代一个给定向量或列表,重复执行某个表达式.for 循环的语法是这样的:for (var in vector) {expr}var 遍历 vector 中的各个元素值,expr 被反复 ...

  6. 7第七章联接和APPLY运算符(转载)

    7第七章联接和APPLY运算符 原文链接 本文由豆约翰博客备份专家远程一键发布

  7. 《On Lisp》第四章第三节图4.6中的rmapcar函数中展现的apply陷阱

    (defun rmapcar (fn &rest args) (if (some #'atom args) (apply fn args) (apply #'mapcar #'(lambda ...

  8. Tsql2008查询性能优化第一章---APPLY

       APPLY运算符涉及以下两个步骤中的一步或两步(取决于APPLY的类型):           1.A1把右表表达式应用于左表的行.           2.A2:添加外部行.       Ap ...

  9. ASP.NET Core 中文文档 第四章 MVC(4.2)控制器操作的路由

    原文:Routing to Controller Actions 作者:Ryan Nowak.Rick Anderson 翻译:娄宇(Lyrics) 校对:何镇汐.姚阿勇(Dr.Yao) ASP.NE ...

随机推荐

  1. jQuery Validate 使用

    jQuery Validate 使用 <script src="js/b/js/jquery.validate.js"></script> <styl ...

  2. Android游戏框架Libgdx使用入门

    转载自:http://blog.csdn.net/cping1982/article/details/6176191 Libgdx作者博客:http://www.badlogicgames.com/ ...

  3. 在mac osX下安装openCV,used for python

    OpenCV是个开源的图像处理库,里面的内容多多. 想了解很多其它,请自行百度咯~ 篇blog是记录在mac下.安装openCV.然后使用python来引用openCV库. 环境是: Python 2 ...

  4. Web实际应用中的编码问题

    一. JSP页面有关编码的介绍 ---->>假设不做不论什么设置,页面默认ISO-8859-1编码(Western European). ---->><%@ page c ...

  5. 使用SetTimer函数为Delphi的Win控件设置时钟

    procedure Timertodo(var messag:Tmessage);message WM_TIMER; procedure TForm1.FormCreate(Sender: TObje ...

  6. oc50--@class1

    // // main.m #import <Foundation/Foundation.h> #import "Person.h" int main(int argc, ...

  7. 阿里云centos系统上安装ftp

    最近需要在一台阿里云的云服务器上搭建FTP服务器,在这篇博文中分享一下我们根据实际需求进行的一些配置. ftp软件用的是vsftpd. vsftpd是一款在Linux发行版中最受推崇的FTP服务器程序 ...

  8. bzoj1725 [Usaco2006 Nov]Corn Fields牧场的安排(状压dp)

    1725: [Usaco2006 Nov]Corn Fields牧场的安排 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 714  Solved: 502 ...

  9. Quartz实现执行任务记录数据库,方便计算任务的执行次数以及成功次数

    任务执行实体 /** * 任务执行情况详情 */ public class JobExecuteDetail implements Serializable{ /** * */ private sta ...

  10. android service--delphixe 10.3

    开发中的陷阱: 1. 别放什么 *.wav文件,这个 服务窗口不能随便放东西,不然铁定出现意想不到的结果,比如 无法运行,因为没 ui界面,随意都不知是啥问题. 2. 不能加载 datamodule ...