1. 问题引入
function A() {}A.prototype.fna = function() { console.log(this);}
我的问题是 fna
的 this
是指向哪里的?
var a = new A();a.fna(); // A {}var fnt = a.fna;fnt(); // window {...}
再看我们经常遇到的情形
function A() { this.name = 'A';}A.prototype.fna = function() { return this.name;}function sayName(fn) { console.log(fn());}var a = new A();sayName(a.fna); //undefinedsayName(a.fna.bind(a)); //A
这里就是我们平时在写代码的时候为什么要调用 bind
函数来绑定上下文
function A() { this.fna = function() { console.log(this); }}A.prototype.getFna = function() { return this.fna;}function sayContext(fn) { fn();}var a = new A();var fna = a.getFna();sayContext(fna); //window
为什么会有以上这种情况呢,在 java
中 this
是始终指向调用对象的。是的,始终指向调用对象,调用对象,这个很重要,java
的静态成员是没有 this
的概念的。在 javascript
中 this
只和函数的执行环境有关。只有三种情况,在浏览中 window、调用对象、严格模式下的undefined,对应我们开发者来说能接触到的就是以上三者,所以我们可以理解为 函数的执行环境就是以上三者。
2. 确定 this
指向
我们如何确定 this
的指向呢,有很多文章介绍 this
确定指向,方式也有很多种,而我是根据函数的调用形势去判断的,有以下两个判断标准。
1 如果函数的最终调用形式是 fn();
那么在非严格模式下 this
指向 window
对象,在严格模式下指向 undefined
o.fn();
这种形式 this
指向对象 o
是的就这两个标准,就这么简单。
3. 通过 call
、apply
、bind
深入理解 this
函数调用原型
fn.call(thisArg, arg1, arg2, ...)
fn.apply(thisArg, [argsArray])
fn.bind(thisArg[, arg1[, arg2[, ...]]])
上面这三个函数都是用来改变函数的 this
指向的
call
第一个参数是 fn
中 this
的期望指向,值可以是 对象
或者 undefined
,后面的参数是要传递 给 fn
的参数列表 2 apply
第一个参数是 fn
中 this
的期望指向,值可以是 对象
或者 undefined
,后面的值是 fn
的 参数,是一个数组
call
和apply
功能相同,唯一不同的是选择将参数以 参数列表
传入或者以 数组
传入,都可以,可以互换
3 bind
第一个参数是 fn
中 this
的期望指向,值可以是 对象
或者 undefined
,后面的参数是要传递 给 fn
的参数列表
调用 bind
函数会返回一个函数,这个函数是 fn
的包装,和 fn
的唯一区别是绑定了 this
,即 this
指向明确。所以 bind
和 call
、apply
,的区别是 bind
返回一个 this
明确的新函数,call
和 apply
立即执行了 fn
。
到这里我想 javascript
的 this
已经说的很清楚了。