关于this
this 提供了一种优雅的方式来隐式“传递”一个对象引用,所以能够将API设计得更加简洁而且易于复用。
/*
*this 隐式传递上下文对象
*/
function identify() {
return this.name.toUpperCase();
}
function speak() {
var greeting = "Hello, I am " + identify.call(this);
console.log(greeting);
}
var me = {
name: "kelly"
}
var you = {
name: "lucy"
}
identify.call(me); //KELLY
identify.call(you); //LUCY
speak.call(me); //Hello, I am KELLY
speak.call(you); //Hello, I am LUCY
随着使用模式愈来愈复杂,显式传递上下文对象会让代码变得愈来愈乱,使用this则不会这样。
对于this的误解
新手会误认为this指向函数自己。
/*
*关于this的误解
*/
function foo(num) {
console.log("foo: " + num);
this.count++;
}
foo.count = 0;
var i;
for (i = 0; i < 10; i++) {
if (i > 5) {
foo(i);
}
}
console.log(foo.count); //0
因而可知,浏览器解析语句产生了4条输出,证实foo(...)确实被调用了4次,可是foo.count仍然是0,显然从字面意思来理解this是错误的。
这时候,可使用Function.call()的方法强制使this指向foo函数对象。
/*
*使用function.call()方法使this指向foo函数对象。
*/
function foo(num) {
console.log("foo: " + num);
this.count++;
}
foo.count = 0;
for (i = 0; i < 10; i++) {
if (i > 5) {
foo.call(foo, i)
}
}
console.log(foo.count);
this 究竟是什么
this是在运行时进行绑定的,并非在编写时绑定,它的上下文取决于函数调用时的各类条件。this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。
当一个函数被调用时,会建立一个活动记录。这个记录会包含函数在哪里被调用、函数的调用方式、传入的参数等信息。this就是这个记录的一个属性,会在函数执行的过程当中用到。
小结
学习this的第一步是明白this既不指向函数自身也不指向函数的词法做用域,抛开之前错误的假设和理解。
this其实是在函数被调用时发生的绑定,它指向什么彻底取决于函数在哪里被调用。