一直以来都知道js的this让初学者很困惑, 但因为在学angularjs的时候潘老师早早的就教咱们写代码时先定义self = this
, 而后经过操做self
, 再以后学习angular又一直使用的箭头函数, 因此js的this
用起来和java的用起来并无什么不一样, 也就没有认真的去学习js的this
和其余语言的到底独特在那里, 本周遇到了一个函数尽然不能使用箭头函数, 又想起了这个问题, 就找了几篇博客学了学。html
让咱们先看几段js代码,并猜猜打印的是什么java
下面的环境都为chrome的控制台, 即非严格模式(即不使用
use strict
, 两种模式下结果不相同)
// 例子1 function a(){ name: 'yunzhi_a'; console.log(this); //? } a(); // 例子2 var b = { name:"yunzhi_b", fn:function(){ console.log(this) // ? } } b.fn(); // 例子3 var c = { name:"yunzhi_c", fn:function(){ console.log(this); // ? } } window.c.fn(); // 例子4 var d = { name: 'yunzhi_d', o: { name: 'object', fn: function(){ name: 'fn' console.log(this); // ? } } } var j = d.o.fn; j();
是否是感受他们都差很少?
公布答案以前, 先说一下this的使用的规则:angularjs
this的指向在函数定义的时候是肯定不了的,只有函数执行的时候才能肯定this到底指向谁, 实际上this的最终指向的是那个调用它的对象
答案是
Window
,为何呢?想一想上面的规则,**this的最终指向的是那个调用它的对象**
,函数没有调用对象,这时this
将指向全局的window
对象。chrome
第二个应该很简单了,仍是上面的规则,此次是b
调用的fn
,因此嘛app
第三个呢,是谁调用的fn
,window
吗?再想一想
复习一下,this的最终指向的是那个调用它的对象
, fn()
是经过谁调用的,是c
调用的,因此打这时的this指向的就是c
ide
看着和上面是差很少的对吧?因此答案就是o
对吧?不对
再看看, 咱们调用的是j
,虽然他是经过fn
赋的值,但咱们确实调用的是前面没有对象的j
, 在例子1
中已经说过了,此时会this
会指向window
。函数
在使用箭头函数时咱们不会遇到这种让人晕乎的this
指向问题post
箭头函数保持它当前执行上下文的
词法做用域不变,而普通函数则不会。换句话说,箭头函数从包含它的词法做用域中继承到了
this
的值。
var object = { data: [1,2,3], dataDouble: [1,2,3], double: function() { console.log("this inside of outerFn double()"); console.log(this); // object return this.data.map(function(item) { console.log(this); // window return item * 2; }); }, doubleArrow: function() { console.log("this inside of outerFn doubleArrow()"); console.log(this); // object return this.dataDouble.map(item => { console.log(this); // objecgt return item * 2; }); } }; object.double(); object.doubleArrow();
是否是对map中的函数是谁调用的感到疑惑了?为何是window
?
由于map中的函数是一个匿名函数,他并无调用者,想到上面的例子了吧,咱们能够看一下map
的基本实现学习
// Array.map polyfill if (Array.prototype.map === undefined) { Array.prototype.map = function(fn) { var rv = []; for(var i=0, l=this.length; i<l; i++) rv.push(fn(this[i])); return rv;
直接使用的fn()
。this
this
在严格模式下指向undefined
。
大部分状况下,开发者使用 this ,并不但愿它指向全局 window 对象。严格模式帮咱们在使用this
关键词时,尽可能少作搬起石头砸本身脚的蠢事。
开发者能够经过bind
、call
和 apply
来主动控制this的指向,固然这里再也不细说,有兴趣能够看这篇文章——JS中call、apply、bind使用指南,带部分原理。。