隐式函数参数:arguments

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

函数上下文:this

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

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

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

1
2
3
4
5
6
7
8
9
10
function ninja() {
return this;
}

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

作为方法被调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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对象的属性方法调用

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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");

返回原始值的构造函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
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");