在函数内部有两个特殊的对象,arguments 和 this,还有一个函数对象的属性caller。

arguments对象

arguments是一个类似数组的对象,包含着传入函数的所有参数。

  1. function doAdd(){
  2. if(arguments.length == 1){
  3. return arguments[0] + 10;
  4. }else if(arguments.length == 2){
  5. return arguments[0] + arguments[1];
  6. }
  7. }
  8. console.log(doAdd(11)); //
  9. console.log(doAdd(11,20)); //

arguments对象还有一个属性callee,该属性是一个指针,指向拥有这个arguments对象的函数。

  1. function factorial(num){
  2.  
  3. if(num <=1){
  4. return 1;
  5. } else {
  6. return num*arguments.callee(num - 1);
  7. }
  8.  
  9. }
    // 消除代码和函数名的耦合。

在严格模式 ("use strict")下,访问 arguments.callee 会出错。

在严格模式下也能实现递归:

  1. var factorial = (function f(num){
  2.  
  3. if(num <=1){
  4. return 1;
  5. } else {
  6. return num*f(num - 1);
  7. }
  8. });
  9. console.log(factorial(4)); //

this对象

this引用的是函数的执行环境对象。在函数调用之前this对象的值是不确定的,在网页浏览器的全局作用域中调用函数时,this对象引用的是window:

  1. window.color = "red";
  2. var o ={
  3. color : "blue"
  4. };
  5.  
  6. function sayColor(){
  7. alert( this.color);
  8. }
  9. sayColor(); // red, 在全局作用域中调用函数,this引用的是window对象
  10.  
  11. o.sayColor = sayColor;
  12. o.sayColor(); // blue, 引用对象o

caller属性

caller属性指向调用该函数的函数,如果是在全局作用域中调用当前函数,它的值为null:

  1. function outer(){
  2. inner();
  3. }
  4. function inner(){
  5. console.log(inner.caller);
    // console.log(arguments.callee.caller);
  6. }
  7.  
  8. outer(); // 打印outer函数的源代码
  9. inner(); //打印null

call()和apply()

每个函数都包含这两个非继承而来的函数,这两个函数的用途都是在特定的作用域中调用函数,实际上等同于在设置函数体内的this对象的值。

apply()有两个参数,第一个是运行时函数的作用域(执行环境)对象,第二个是参数对象,可以是arguments对象,或者是数组

call()函数的第一个参数也是作用域对象,其余参数是传递给函数的参数,需要逐个列出来

apply()和call()最常用的场景是改变函数运行的作用域。这样对象就可以不需要和方法有任何耦合的关系

  1. var color = "red";
  2. var o = {"color":"blue"};
  3. function sum(num1,num2){
  4. console.log(this.color);
  5. return num1+num2;
  6. }
  7. function callSum1(num1,num2){
  8. return sum.apply(this, arguments);
  9. }
  10. function callSum2(num1,num2){
  11. return sum.apply(this, [num1,num2]);
  12. }
  13.  
  14. function callSum3(num1,num2){
  15. return sum.call(this, num1,num2);
  16. }
  17.  
  18. o.callSum1 = callSum1;
  19. o.callSum2 = callSum2;
  20.  
  21. console.log(callSum1(10,10)); // red 20
  22. console.log(callSum2(10,10)); // red 20
  23. console.log(callSum1.apply(o,[10,10])); // blue 20
  24. console.log(callSum3.call(o,10,10)); // blue 20,直接改变作用域
  25. console.log(o.callSum1(5,10)); // blue 15
  26. console.log(o.callSum2(5,10)); // blue 15

 bind()

bind()函数会创建一个函数实例,新的函数的this值为被绑定为传给bind()函数的值

  1. var color = "red";
  2. var o = {"color":"blue"};
  3.  
  4. function sayColor(){
  5. console.log(this.color);
  6. }
  7. var objectSayColor = sayColor.bind(o);
  8. objectSayColor(); // blue, 即使在全局中调用,this值仍为对象o

js中函数的 this、arguments 、caller,call(),apply(),bind()的更多相关文章

  1. JS中函数参数和函数返回值的理解

    函数本质就是功能的集合 JS中函数是对象,因此,函数名实际上仅仅是一个指向函数对象的指针,不会与某个函数绑定,所以,JS中没有重载(重载就是通过传递不同类型的参数,使两个相同函数名的函数执行不同的功能 ...

  2. js中函数传参的情况

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  3. 对JS中函数的理解

    函数本质就是功能的集合 JS中函数是对象,因此,函数名实际上仅仅是一个指向函数对象的指针,不会与某个函数绑定,所以,JS中没有重载(重载就是通过传递不同类型的参数,使两个相同函数名的函数执行不同的功能 ...

  4. 关于js中函数的调用问题

    js中函数的调用方法 1.直接调用 函数名(参数): 2.通过指向函数的变量去调用 例如: var myval = 函数名: 此刻 myval是指向函数的一个指针: myval(实际参数):此刻调用的 ...

  5. JS中函数void()

    <a href="javascript:void(0)">hello</a>/* * JS中函数void()的运用大体是这种新式; * void()是运算符 ...

  6. js中函数的参数为函数的情况即回调函数

    js中函数的参数可以是数组对象也可以是函数,当参数为函数时我们叫做回调函数 //定义回调函数function B() { console.log("函数B")setTimeout( ...

  7. JS中函数的调用和this的值

    调用每一个函数会暂停当前函数的执行,传递控制权和参数给新函数.除了声明时定义的形式参数,每个函数还接收两个附加的参数:this 和 arguments. 参数this在面向对象编程中非常重要,他的值取 ...

  8. js 中arguments,call,apply,bind的使用

    //对于 arguments和this, 每个函数都有自己独有的arguments和this, 且不进行链式查找 //arguments是什么? //答:1:arguments是收到的实参副本 //2 ...

  9. js中函数this的指向

    this 在面试中,js指向也常常被问到,在开发过程中也是一个需要注意的问题,严格模式下的this指向undefined,这里就不讨论. 普通函数 记住一句话哪个对象调用函数,该函数的this就指向该 ...

随机推荐

  1. fabric镜像安装脚本分析

    #!/bin/bash # # Copyright IBM Corp. All Rights Reserved. # # SPDX-License-Identifier: Apache-2.0 # e ...

  2. js全局变量污染

    一.定义全局变量命名空间 只创建一个全局变量,并定义该变量为当前应用容器,把其他全局变量追加在该命名空间下 var my={}; my.name={ big_name:"zhangsan&q ...

  3. iPhone投影

    iPhone投影到Mac上面的操作,用QuickTime,选择主菜单的新建屏幕录制,然后点击录制按钮右边的箭头,相机切换到iPhone就可以了. 相关操作参照 https://jingyan.baid ...

  4. Windows下卸载Apache、Mysql

    卸载Apache 1. 停止服务 2.以管理员身份打开命令环境 3. 删除Apache文件目录 卸载Mysql 一.在控制面板,卸载MySQL的所有组件控制面板——>所有控制面板项——>程 ...

  5. element——message-box

    `${action}`可以捕获用户选择cancel还是confirm,然后进行相应操作 官方文档:http://element-cn.eleme.io/#/zh-CN/component/messag ...

  6. J2SE 8的流库 --- 转换流, 得到的还是流

    流的转换, 按照条件过滤/映射/摊平/截取/丢弃/连接/去重/排序. 辅助方法 public static int myCompare(String x, String y) { if(x.lengt ...

  7. day23-类的封装

    1.封装 封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容.所以,在使用面向对象的封装特性时,需要:1)将内容封装到某处2)从某处调用被封装的内容 第一步:将内容封装到某处 cl ...

  8. Centos7 Minimal 安装后 初始化配置

    安装完成后初始化配置 1:更新yum yum upgrade 2: 安装基础命令 #yum -y install vim* lrzsz gcc-c++ pcre pcre-devel zlib zli ...

  9. CSS COLOR

    CSS COLOR Color Review We've completed our extensive tour of the colors in CSS! Let's review the key ...

  10. c中计时函数 clock()

    #include<time.h> int main() { // ... .. // .... printf("Time used = %.2lf\n",(double ...