关于Javascript中的this

这周看了好多关于this的文章。

比较好的博文有如下几篇

ES5中的this:

1. http://javascript.ruanyifeng.com/oop/this.html#toc7。(主要关于this的动态指向call/apply/bind说的比较清楚)

2. https://mp.weixin.qq.com/s/rlFJAiD1YWb065juEe4sNg (推荐,有对this用法分类,以及函数中的this的方法总结)

ES6中的this(Array Function中的this):

3. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this (Array Function中的那一节)

4. http://es6.ruanyifeng.com/#docs/function(箭头函数那一节)

5. https://derickbailey.com/2015/09/28/do-es6-arrow-functions-really-solve-this-in-javascript/

读到ES6中的this会涉及到一个“lexical scoping”词法作用域的概念。

6. http://blog.csdn.net/liwenfei123/article/details/77965838(推荐)

7. http://pierrespring.com/2010/05/11/function-scope-and-lexical-scoping/


阅读顺序可以是:2 -> 3 。

(看完2后,需要对2中函数中的this有一个比较清楚的认识。其中1跟4都是阮一峰老师的,可以作为进阶,里面讲的比较细,点很多。)

如果你JS基本功很好,读了2跟3基本就理解。若你不好,就会有很多问题,比如

3里面提到的 In arrow functionsthis retains the value of the enclosing lexical context's this

4里面提到的 箭头函数导致this总是指向函数定义生效时所在的对象(本例是{id: 42}),所以输出的是4

5里面提到的 The ES6 arrow function syntax uses “lexical scoping” to figure out what the value of “this” should be. Lexical scoping is fancy way of saying it uses “this” from the surrounding code… the code that contains the code in question.

什么“enclosing lexical context” ,“定义生效时”, “lexical scoping”看了就晕菜。

或许是我JS比较菜。当我看完6跟7后基本就明白了,这些就是词法作用域,也叫静态作用域。跟它相对是动态作用域。但是JS采用的是静态作用域。什么叫静态,静态就是在初始化执行上下文的时候就生成了的,运行的时候无法改变的作用域。说白了就作用域链,如果一个inner function 查找一个变量不能在自己的inner function scope找到,就会一层一层得向parent functions查找,直到找到全局作用域(浏览器为window,而node为module)为止。

7中还有一段话:

Lexical Scoping defines how variable names are resolved in nested functions. Other names of Lexical Scoping are Static Scoping or Closure. It means that the scope of an inner function contains the scope of a parent function。

Other names of Lexical Scoping are Static Scoping or Closure。Lexical Scoping 又叫闭包?

不过It means that the scope of an inner function contains the scope of a parent function 好像说的确实也对。这里还得思考下。

关于词法作用域的一个demo:

var a = 1;
function foo() {
    console.log(a);
}
function bar() {
    var a = 2;
    foo();
}
bar(); //这里输出的是1,不是2.因为在创建执行上下文栈的时候,就已经确定了。foo作用域链的上面节点用于是全局作用域

而ES6箭头函数中的this也是采用了这个词法作用域,先给出几篇博文中的例子。

function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

var id = 21; 
foo.call({ id: 42 });//42 
//why? 因为箭头函数本身自己是没有this的,从执行上下文来看,箭头函数的parent scope是foo,所以向上找,找到了foo中的this,
而通过call将foo中的this 指向了{id:42}。所以输出42

var obj = {bar: function() {
                    var x = () => this;
                    return x;
                  }
          };
var fn = obj.bar();
console.log(fn() === obj); //true 因为 ()=> this 中的this指向bar的function的this,而bar的function是自己的this的拥有者,bar function的调用者是obj,
//所以,bar的function的this指向obj. 进而 ()=> this 中的this指向obj。
var fn2 = obj.bar;//这里讲bar的function赋于fn2,就是()=> this 中的this指向fn2的function中的this,
//fn2是自己this的拥有者,fn2的调用者是window,所以fn2中的this指向window,进而()=> this 中的this也是指向window。
console.log(fn2()() == window);//true
this.test = "attached to the window";
var foo = {
  test: "attached to an object"
};

foo.method = function(name, cb){
  
  // bind the value of "this" on the method
  // to try and force it to be what you want
  this[name] = cb.bind(this);//这里视图在运行过程中改变箭头函数中this的指向
  
};

foo.method("bar", () => {//在生成执行上下文的时候,就已经确定bar的function 的this指向了window,所以视图在运行过程中改变箭头函数的this指向是无效的
  console.log(this.test); 
});

foo.bar();//attached to the window




这样,就对this的指向有了一个比较明白的解释。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值