• this:表示被调用函数的上下文对象。
  • arguments:表示函数调用过程中传递的所有参数。
  • 这两个参数都是隐式的函数参数。会静默传递给函数,并且和函数体内显式声明的参数一样可正常访问。
  • arguments有length属性,可以通过下标方式访问每个元素,但是它不是数组,是类数组。

函数调用的四种方式:区别主要在于this值得不同。 (对于作为方法调用而言,this为方法所在的对象//   对于顶级函数this 则为window或undefined//   对于构造函数而言this为新创建的实例)

  • 作为一个函数(function)---test(),直接被调用。

    function test(){
    //函数体 -------函数定义作为函数被调用
    }
    test(); var test=function(){ };
    test(); --------------函数表达式作为函数调用

    当以上面的方式调用,函数的上下文(this)有两种可能性:在非严格模式下,会是全局上下文(window对象);在严格模式下,是undefined。

         function test(){
    console.log(this); //window
    }
    test();
  • 作为一个方法(method)---ml.test(),关联在一个对象上。

    var obj1={
    getMythis:test
    };
    var obj2={
    getMythis:test
    };
    function test() {
    console.log(this);
    }
    obj1.getMythis(); //返回上下文 对象obj1
    obj2.getMythis(); //返回上下文 对象obj2

    通过this在任何方法中的引用该方法的宿主对象。调用同样的方法 但由于对象不同 返回的上下文也不同。

  • 作为一个构造函数---new test(),实例化一个新对象。

通过构造函数的方式调用时,需要在函数调用之前加上关键字new。上例中函数test 的构造函数调用方式为:

var obj=new test();

通过new 关键字调用时会创建一个空的对象实例,并将其作为函数上下文(this参数)传递给函数。在构造函数中创建的属性和方法会在实例化后赋值给该对象。

调用构造函数时会发生如下操作:

  1. 创建一个新的空对象。
  2. 该对象作为this参数传递给构造函数,从而构成构造函数的函数上下文。
  3. 新构造的对象作为new运算符的返回值。

     构造函数的目的:创建一个新对象,并进行初始化设置,然后将其作为构造的返回值。将返回结果存储在变量中,后续通过这些变量引用新创建的对象。

     即:初始化新创建的对象。

    var puppet={
rule:false
};
function Emperor(){
this.rules=true;
return puppet;
}
var emperor=new Emperor();
console.log(emperor===puppet); //true

打印结果 emperor为对象,包含属性rules,而不是Emperor函数调用后的返回值。

总结:

  1. 如果构造函数返回一个对象,则该对象将作为整个表达式的值返回,而传入构造函数的this将会被废弃。
  2. 但是,如果构造函数返回是非对象类型,则忽略返回值,返回新创建的对象。
  • 通过函数的apply和call方法                 ---sk.call(test)  /   sk.apply(test); 用法区别是:如何传参。
     function Button(){
this.clicked=false;
this.click=function(){
this.clicked=true;
console.log(button.id);
}
}
var button=new Button();
var elem=document.getElementById("test");
elem.addEventListener("click",button.click); //undefined

原因:  click函数的上下文并非执行button对象。上下文为按钮即:button元素,并非button对象。

更正

 1     function Button(){
2 this.clicked=false;
3 this.click=function(){
4 this.clicked=true;
5 console.log(button.id);
6 }
7 }
8 var button=new Button();
9 var elem=document.getElementById("test");
10 elem.addEventListener("click",button.click.bind(button));
//test

call  和apply  实际使用方法:

    function Sum(){
var result=0;
for(var i=0;i<arguments.length;i++){
result+=arguments[i];
}
return this.result=result;
}
var test1={};
var test2={};
Sum.apply(test1,[1,2,3,4]);
Sum.call(test2,5,6,7,8);
console.log(test1.result); //
console.log(test2.result); //

其中Sum作为test1和test2对象的方法被调用,且函数上下文指向这些对象。实质为Sum函数的正常调用,只不过函数上下文为括号内传入的对象,手动设置函数上下文。

  • 解决函数上下文的另外两种选择:箭头函数和bind方法。

箭头函数的this不会隐式传入,从定义时的函数继承上下文。如下例子所示:

  var button= {
clicked: false,
click:()=>{
this.clicked = true;
console.log(button.clicked);
}
}
8 button.click(); //false
9 console.log(window.clicked); //true

因为click箭头函数是作为对象字面量的属性定义的,对象字面量是在全局代码中定义的,因此,箭头函数内部this与全局对象的this值相同。

  • bind方法:创建并返回一个新函数,并绑定在传入的特定的对象上。函数体与原函数一致。

 bind,apply,call异同:

共同点:都是改变this对象的指向问题。

区别:

1、bind返回值是新的函数,必须调用才能执行,后两者均为立即执行。

2、apply和call的传参方式不同,apply为传入数组,而call为一个个传入。bind和call传参类型相同。

函数调用的四种方式 和 相关的 --- this指向的更多相关文章

  1. python函数调用的四种方式 --基础重点

    第一种:参数按顺序从第一个参数往后排#标准调用 # -*- coding: UTF-8 -*- def normal_invoke(x, y): print "--normal_invoke ...

  2. C#批量插入数据到Sqlserver中的四种方式

    我的新书ASP.NET MVC企业级实战预计明年2月份出版,感谢大家关注! 本篇,我将来讲解一下在Sqlserver中批量插入数据. 先创建一个用来测试的数据库和表,为了让插入数据更快,表中主键采用的 ...

  3. 【Java EE 学习 80 下】【调用WebService服务的四种方式】【WebService中的注解】

    不考虑第三方框架,如果只使用JDK提供的API,那么可以使用三种方式调用WebService服务:另外还可以使用Ajax调用WebService服务. 预备工作:开启WebService服务,使用jd ...

  4. C#_批量插入数据到Sqlserver中的四种方式

    先创建一个用来测试的数据库和表,为了让插入数据更快,表中主键采用的是GUID,表中没有创建任何索引.GUID必然是比自增长要快的,因为你生成一个GUID算法所花的时间肯定比你从数据表中重新查询上一条记 ...

  5. iOS 登陆的实现四种方式

    iOS 登陆的实现四种方式 一. 网页加载: http://www.cnblogs.com/tekkaman/archive/2013/02/21/2920218.ht ml [iOS登陆的实现] A ...

  6. 实现web数据同步的四种方式

    http://www.admin10000.com/document/6067.html 实现web数据同步的四种方式 1.nfs实现web数据共享 2.rsync +inotify实现web数据同步 ...

  7. JAVA解析XML的四种方式

    java解析xml文件四种方式 1.介绍 1)DOM(JAXP Crimson解析器) DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准.DOM是以层次结构组织的节点或信息片断的集合.这 ...

  8. Action中取得request,session的四种方式

    Action中取得request,session的四种方式 在Struts2中,从Action中取得request,session的对象进行应用是开发中的必需步骤,那么如何从Action中取得这些对象 ...

  9. 关于this绑定的四种方式

    一.前言 我们每天都在书写着有关于this的javascript代码,似懂非懂地在用着.前阵子在看了<你不知道的JavaScript上卷>之后,也算是被扫盲了一边关于this绑定的四种方式 ...

随机推荐

  1. frambuffer 相关函数理解

    1. framebuffer_alloc()功能是向内核申请一段大小为sizeof(struct fb_info) + sizeprivate的空间,其中sizeprivate的大小代表设备的私有数据 ...

  2. centos7升级内核

    载入elrepo源,搜索内核更新资源,并进行更新操作. 具体实验步骤: # 载入公钥rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org ...

  3. CentOS6.5安装MySQL5.7详细教程(本人6.3也行)

    本文参考http://www.cnblogs.com/lzj0218/p/5724446.html 主要参考博文: https://segmentfault.com/a/119000000304949 ...

  4. Eclipse git 冲突合并

    Eclipse有一个git的插件叫EGit,用于实现本地代码和远程代码对比.合并以及提交.但是在本地代码和远程代码有冲突的时候,EGit的处理方案还是有点复杂.今天就彻底把这些步骤给理清楚,并公开让一 ...

  5. BOM进IN_BOM_HEADER表后被过滤掉

    1.查看如下两个表发现BOM被过滤掉了 SELECT  PRODUCT_ID||'_'||substr(BOM_ID,1,8),A.* FROM IN_BOM_HEADER A WHERE A.PRO ...

  6. 使用tor网络

    在www.torproject.org/projects/torbrowser.html.en上找到合适的版本下载 下载好tor浏览器之后,解压双击Tor Browser,出现这个错误 这是因为kal ...

  7. JMeter学习(四)参数化(转载)

    转载自 http://www.cnblogs.com/yangxia-test JMeter也有像LR中的参数化,本篇就来介绍下JMeter的参数化如何去实现. 参数化:录制脚本中有登录操作,需要输入 ...

  8. 织梦 百度sitemap制作教程

    一.新建一个sitemap.htm模板 登录dedecms后台,选择[模板]-[模板管理]-[默认模板管理] 点击最下面的[新建模板]新建一个模板,并复制下面这段代码进去(将代码中的域名改为自己的): ...

  9. ffmpeg编码中的二阻塞一延迟

    1. avformat_find_stream_info接口延迟 不论是减少预读的数据量,还是设置flag不写缓存,我这边都不实用,前者有风险,后者会丢帧,可能我还没找到好姿势,记录在此,参考:htt ...

  10. Driver stacktrace: at org.apache.spark.scheduler.DAGScheduler.org$apache$spark$scheduler$DAGSchedul

    在写Spark程序是遇到问题 Driver stacktrace: at org.apache.spark.scheduler.DAGScheduler.orgapacheapachesparksch ...