理解Javascript中this

作者: 小胖子littlefatboy | 来源:发表于2017-05-23 15:57 被阅读0次

在 学习JavaScript 的过程中,this 这个关键字常常困扰着初学者甚至一些进阶的开发者;尤其对一些学过面向对象编程的同学来说,JS中的this含义会很不一样。下面就来说说怎么理解Javascript中的this关键字。

Javascript中函数的调用方式

首先我们来看看javascript中函数的调用方式:

function func(argu[0], argu[1]){
//define a function func
}
var obj = {  //define a object obj
    func: function(argu[0], argu[1]){
    //define a method func in object
    }
}

func(argu[0], argu[1])  
obj.func(argu[0], argu[1])  //call the function func

上面的调用方式是我们经常使用的形式,称为语法糖。上述形式可以等价转换为function.call的形式:

func.call(undeined, argu[0], argu[1])
//函数调用call形式,等价于func(argu[0], argu[1])

obj.func.call(obj, argu[0], argu[1])
//对象方法call形式,等价于obj.func(argu[0], argu[1])

这样,JS中的this就很好理解了。

this 是 JavaScript 中的一个关键字,当一个函数被调用时,除了传入函数的显式参数以外,名为 this 的隐式参数也被传入了函数。this 参数指向了一个自动生成的内部对象,这个内部对象被称为函数上下文(context)。

<strong>this的指向时动态的,有办法事先确定到底指向哪个对象,只有执行函数时才能确定。</strong>

与其他面向对象的语言不同的是, JavaScript 中的 this 依赖于函数的调用方式。所以,想要明白 this 的指向问题,还必须先研究函数在 JavaScript 中是如何被调用的。

在全局上下文中

在全局运行上下文中(在任何函数体外部),this指代全局对象,无论是否在严格模式下('use strict')

//在浏览器中,全局对象为window
console.log(this === window)  //true

this.name = 'frank'
console.log(window.name) //print frank

在函数上下文中

取决于函数如何调用:

1. 作为函数进行调用

在非严格模式下,不在调用时设置this值的时候(使用语法糖),this的值会默认设置为全局对象:

  function test(){
    console.log(this)
  }

test() //print window

而在严格模式下,this将保持他进入执行环境时的值,不设置为undefined:

  function test(){
    "use strict";  //使用严格模式
    console.log(this)
  }

test() //print undefined

2. 作为方法进行调用

当一个函数被一个对象的属性引用时,可以通过对象调用这个函数:

var obj = {
  func: function() {
    console.log(this)
  }
}

obj.func()  //print obj

函数 func 的调用对象为 obj,所以函数上下文便是 obj。由此可见,将函数作为对象的一个方法进行调用时,该对象就是函数上下文,并且在函数内部可以用 this 来访问这个对象。

<strong>但是,当a对象的方法被赋予b对象,该方法就变成了普通函数,其中的this就从指向a对象变成了指向b对象。</strong>

var obj = {
  func: function() {
    console.log(this)
  }
}

var  temp = obj.func
temp()  //print window(global)

3. 使用 apply() 和 call() 方法进行调用

JavaScript 的每个函数都有 apply() 和 call() 函数,可以利用任何一个函数都可以显式指定任何一个对象作为其函数上下文。

通过 call() 方法来调用函数,我们要给 call() 传入一个this作为函数上下文对象,另外还要传入函数原本的参数。apply() 方法的使用方式类似,唯一不同的是call()方法传入的所有参数,而apply()是传入的参数数组。

我们使用call为例:

function func() {
    let result = 0;
    for(let i = 0; i < arguments.length; i++) {
        result += arguments[i];
    }
    this.result = result;
}
var obj = {}
func.call(obj, 1, 2, 3) 

obj.result  === 6  //the result is 6

将函数的上下文定义为 obj,并且传入 1、2、3 三个参数,func.call(obj, 1, 2, 3)。由于this指向了obj,在执行完函数后,obj中的result属性变为6。

同样,利用call()或者apply()方法,我们可以在一个对象中调用另一个对象中的函数:

var array1= []
var array2= []  //define 2 arrays

array1.push.call(array2, 1, 2, 3)  //在array1中调用array2的push方法
console.log(array1)  //print []
console.log(array2)  //print [1, 2, 3]

在上述例子中,定义了两个数组array1和array2,通过array1调用了array2中的push方法,最后改变了array2。

由于有call()和apply()方法,这就使得Javascript非常灵活。

4. 作为构造器进行调用

ES6中箭头函数与this

参考文章

相关文章

  • 理解Javascript中this

    在 学习JavaScript 的过程中,this 这个关键字常常困扰着初学者甚至一些进阶的开发者;尤其对一些学过面...

  • JavaScript中‘this’理解

    1. this之谜 在JavaScript中,this是当前执行函数的上下文。因为JavaScript有4种不同的...

  • 理解 JavaScript 中的内存管理(Memory Mana

    理解 JavaScript 中的内存管理(Memory Management) 平时写 JavaScript 代码...

  • javascript中this的理解

    早期的博客2this是javascript的一个关键字,代表函数运行时,自动生成的一个内部对象,只能在函数内部使用...

  • 理解JavaScript中的this

    前言 做为一个初学者,原型与闭包可以说是 JavaScirpt 中理解起来最难的部分了,当然,目前了解的也只是了解...

  • 理解JavaScript中的this

    理解this JavaScript中的this是其灵活性的表现,同时也因为this的多变性与其他语言的不一致,也成...

  • 理解Javascript中的this

    首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁...

  • javascript中this的理解

    this在javascript中一直是新手难以理解的一部分。其实并不难,只要清楚几种调用模式,就容易掌握了。 函数...

  • Javascript学习笔记-原型链

    对于Javascript原型链,是Javascript中很重要的内容,要理解关键有三点:Javascript中原型...

  • 理解JavaScript中浅拷贝和深拷贝的区别

    要理解 JavaScript中浅拷贝和深拷贝的区别,首先要明白JavaScript的数据类型 JavaScript...

网友评论

    本文标题:理解Javascript中this

    本文链接:https://www.haomeiwen.com/subject/ynbwxxtx.html