this指向的一个疑问

问题描述

《JavaScript设计模式与开发实践》P215第5行代码为什么要改变__self的this指向?它原先的this指向是什么?

相关代码

Function.prototype.before = function( beforefn ) {
    var __self = this;
    return function() {
        beforefn.apply( this, arguments );
        return __self.apply( this, arguments ); // __self原先的this指向不是document吗?为什么这里要改变this指向?
    }
}
document.getElementById = document.getElementById.before(function(){
    alert (1);
});
var button = document.getElementById( 'button' );
阅读 2.3k
3 个回答

兄弟,你这段代码涉及两个问题:JS的面向对象this的指向

Function.prototype是什么?Function.prototypeFunction这个类的原型,这上面挂载的方法都是Function这个类的实例方法。JS里面所有函数都是Function的一个实例,所以当你运行document.getElementById.before
的时候getElementById是一个函数,所以他是Function的实例,他来调用实例方法before,这时候before里面的this指向的是getElementById这个函数。before里面返回了一个匿名函数,这个匿名函数先调用了before传入的回调,然后调用了_self函数,也就是上面的this,也就是getElementById函数。这个匿名函数取代了原生的getElementById
那这个匿名函数里面的this指向谁呢?this指向有一个一般原则:

  1. 作为实例方法调用的,this指向这个实例,比如getElementById是Function的一个实例
  2. 有明确调用者的,this指向明确调用者
  3. 没有明确调用者的,this指向全局对象,浏览器是window,node里面是global

所以这个匿名函数是被谁调用的呢?答案是你使用的时候是document.getElementById(),调用者是document,所以匿名函数里面的this指向document。见下图:

image.png

JS的面向对象this的指向是JS里面比较基础但又很重要的两个问题,这么几句话说得也不完整,推荐你看看这两篇文章:
JS面向对象的:https://segmentfault.com/a/11...
this指向的: https://segmentfault.com/a/11...

原先匿名函数的this指向的是window

1.this指向当前作用域 .. 从来不指向 document,
2.函数的作用域指向自身,所以嵌套的函数 this 是不统一的
3.当 function 内部没有定义的时候,变量会向上级作用域获取
4.如果用 ES6 的箭头函数可以解决统一的 this 的问题,我记得箭头函数是没有指向自己的 this 的

(function(){
    this.a = 1;
    (() => {console.log(this.a)})()
})()
推荐问题
宣传栏