隐式函数参数:arguments

arguments:不代表数组,允许我们访问传递给函数的所有参数。自带length属性。 arguments代表参数的别名,更改对象arguments的值会影响对应的函数参数。 arguments在strict模式下无法使用。arguments和参数值不互通(strict模式下)。

函数上下文:this

this:面向对象编程的重要组成部分。 this通常指向定义当前方法的类的实例。 函数有四种调用方式:

(function):func()直接调用->此模式下调用,this为Windows对象(全局上下文),严格模式下为undefined
(method):ninja.func()关联对象,实现面向对象编程
(constructor):new ninja()实例化新对象
(apply或call):func.apply/call(ninja)

调用的方式不一样,返回的上下文也不一样 作为函数被调用:

function ninja() {
    return this;
}

function samurai() {
   "use strict";//严格模式
    return this;
}
ninja();
samurai();

作为方法被调用:

function whatsMyContext() {
      return this;
    }

assert(whatsMyContext() === window,
  "Function call on window");

var getMyThis = whatsMyContext;

assert(getMyThis() === window,
  "Another function call in window");

var ninja1 = {
   getMyThis: whatsMyContext
};

assert(ninja1.getMyThis() === ninja1,
   "Working with 1st ninja");//getMyThis作为ninja对象的属性方法调用

作为构造函数调用://初始化和实例对象

function Ninja() {
   this.skulk = function() {
   return this;
   };
}

var ninja1 = new Ninja();//创建一个新的空对象,该对象作为this参数传递给构造函数
var ninja2 = new Ninja();//新构造的对象作为new运算符的返回值

assert(ninja1.skulk() === ninja1,
   "The 1st ninja is skulking");
assert(ninja2.skulk() === ninja2,
   "The 2nd ninja is skulking");

返回原始值的构造函数:

function Ninja() {
    this.skulk = function () {
      return true;
    };

    return 1;
  }
  assert(Ninja() === 1,//作为函数调用返回值是1
    "Return value honored when not called as a constructor");

  var ninja = new Ninja();//作为构造函数调用,返回值是一个对象

  assert(typeof ninja === "object",
    "Object returned when called as a constructor");
  assert(typeof ninja.skulk === "function",
    "ninja object has a skulk method");

使用apply和call方法:

function juggle() {
      var result = 0;
      for (var n = 0; n < arguments.length; n++) {
        result += arguments[n];
      }
      this.result = result;
    }

    var ninja1 = {};
    var ninja2 = {};

    juggle.apply(ninja1,[1,2,3,4]);//this:ninja1 传入一个this和一系列参数
    juggle.call(ninja2, 5,6,7,8);//this:ninja2 传入一个this和一系列参数

    assert(ninja1.result === 10, "juggled via apply");
    assert(ninja2.result === 26, "juggled via call");

使用forEach迭代方法可以将函数的上下文设置为任意的对象 箭头函数没有单独的this值,其this值与箭头函数的上下文相同

使用bind方法:

    var button = {
      clicked: false,
      click: function(){
        this.clicked = true;
        assert(button.clicked,"The button has been clicked");
      }
    };
    var elem = document.getElementById("test");
    elem.addEventListener("click", button.click.bind(button));//使用bind函数创建新函数,绑定到button对象上

    var boundFunction = button.click.bind(button);
    assert(boundFunction !== button.click,
           "Calling bind creates a completyl new function");