this指向调用它的对象

首先要明确,this指向调用方,谁调用,this指向谁。

直接调用

举个栗子:

var
test = 'window'
;
function testThis () {
var test = 'inner';
this.test = 'test change';
console.log(this.test)
}
testThis(); // test change
console.log(window.test) // test change

在chrome中执行后可以发现,外部挂在window下的test被修改了,因为这个testThis的函数,是被window调用的,它只会读取window下的test。

构造函数调用

再举个栗子:

var
test = 'window'
;
function testThis () {
var test = 'inner';
console.log(this.test)
this.test = 'test change';
console.log(this.test)
}
var newTestThis = new testThis();
// undefined
// test change
console.log(window.test) // window

在chrome中执行以下可以发现,依次输出undefined、test change、window。

这个栗子与上面的区别在于调用了new。此时,该函数作为构造函数调用,我们都知道,构造函数中的this都指向new出来的对象。所以this指向了这个新生成的newTestThis。自然地,window下test就没有被修改。

嵌套调用

接下来举一个栗子,来说明在函数嵌套调用时的this指向:

var x = 'global'
function testThis () {
// this.x = 'fuck';
// console.log(this)
console.log(this.x)
}
function innerObj () {
this.x = 'inner';
testThis();
this.innerTestThis = testThis;
this.innerTestThis();
} function wrapObj () {
this.x = 'wrap';
// var test = new testThis();
// console.log(test.x)
testThis(); this.wrapTestThis = testThis;
this.wrapTestThis(); this.innerTestThis = new innerObj();
}
var wrap = new wrapObj();
wrapObj();
// global
// wrap
// global
// inner
// wrap
// wrap
// wrap
// inner

很明显,在函数嵌套时,如果不给函数指定调用对象,则不论被调用函数是在哪个函数的作用域里,被调用的函数的this都是指向window的。

我们可以这样理解,在直接调用时,这些函数除了拥有自己的作用域外,就像是把这几行代码写到了相应的位置。可以想一下,所有的js代码最后都拼到一起,很明显,他们的调用方都是window。

总结一下:1.不论函数在哪里被调用,只要没有指定调用方,则this都指向window。指定了调用方,就指向调用方。2.作为构造函数中调用,this指向新生成的对象。

分析一下:setTimeout和setInterval

bind的作用就是给函数一个指定的thisArg,经常使用bind的地方就是setTimeout和setInterval了。为什么呢?

setTimeout和setInterval都有一个特点,它会将回调函数的作用域转移到window上面。其实结合我们上面说的,很容易知道为什么。

以setTimeout为例:翻看MDN下setTimeout的定义,可以发现,setTimeout是把一段callback代码延迟执行。写过callback的同学都知道,callback的代码其实就是占了位,然后去调用一行行的代码,所以,callback中的this也会指向window。

实际开发中,我们不希望this指向window,故而常使用bind来使this指向我们希望的对象。

bind、apply、call

说到了bind,就还需要提一下另外的可以改变this指向的方法:apply和call。

这两个函数大同小异,只是传参有区别。不论使用apply还是call,都会传入一个thisArg,作为函数调用方,让函数中的this指向thisArg。

在下一篇,我会介绍一下apply和call。

最新文章

  1. DataGridView 在下拉框添加下来事件
  2. [转载]CAsyncSocket及CSocket注解
  3. strtok&strsep
  4. 百度Hi之CSRF蠕虫攻击
  5. Thread: BooleanRT : Realtime 3D boolean operations for (Runtime,Editor)
  6. javascript-03
  7. 【号外号外:微软收购 .NET 的开源实现 Xamarin 项目的公司】
  8. 依赖注入及AOP简述(十一)——生命周期管理 .
  9. 相对协议-关于src里//开头的知识
  10. 对.Net Core结合Docker和Jexus的实践
  11. PHP+MySQL分页显示示例分析
  12. Android常用的技术框架与博客社区
  13. [P1396]营救 (并查集)
  14. 加密、签名和SSL握手机制细节
  15. 【轻松前端之旅】​CSS选择器中的空格与尖括号有何区别?
  16. Spring容器技术内幕之内部工作机制
  17. JAVA个人小程序GUI篇-收银(标签、按钮、复选框、下拉标、文本域、表格······)
  18. 【letcode】5-LongestPalindromicSubstring
  19. # 蜗牛慢慢爬 LeetCode 21. Merge Two Sorted Lists [Difficulty: Easy]
  20. Linux 各类设置、配置、使用技巧参考,Linux使用集锦

热门文章

  1. JavaSE(十)集合之List
  2. kickstart部署及使用
  3. NET Core度身定制的AOP框架
  4. Java多线程之Executor、ExecutorService、Executors、Callable、Future与FutureTask
  5. 201521123004《Java程序设计》第8周学习总结
  6. JAVA课设--五子棋--团队博客
  7. 201521123117 《Java程序设计》第14周学习总结
  8. 详解go语言的array和slice 【一】
  9. Python学习笔记009_构造与析构
  10. Java实现3DES加密--及ANSI X9.8 Format标准 PIN PAN获取PIN BlOCK