网页设计 百分网手机站

深入理解Javascript中的this关键字

时间:2020-11-13 17:34:06 网页设计 我要投稿

深入理解Javascript中的this关键字

  文章主要介绍了深入理解Javascript中的this关键字,本文讲解了方法调用模式、函数调用模式、构造器调用模式、apply调用模式中this的不同之处,需要的朋友可以参考下,就跟随百分网小编一起去了解下吧,想了解更多相关信息请持续关注我们应届毕业生考试网!

  自从接触javascript以来,对this参数的理解一直是模棱两可。虽有过深入去理解,但却也总感觉是那种浮于表面,没有完全理清头绪。

  但对于this参数,确实会让人产生很多误解。那么this参数到底是何方神圣?

  理解this

  this是一个与执行上下文(execution context,也就是作用域)相关的特殊对象。因此,它可以叫作上下文对象(也就是用来指明执行上下文是在哪个上下 文中被触发的对象)。

  任何对象都可以做为上下文中的this的值。在一些对ECMAScript执行上下文和部分this的描述中的 所产生误解。this经常被错误的描述成是变量对象的一个属性。 再重复一次:

  this是执行上下文的一个属性,而不是变量对象的一个属性。 这个特性非常重要,因为与变量相反,this从不会参与到标识符解析过程。换句话说,在代码中当访问this的时候,它的值是直接从执行上下文中获取的,并不需要任何作用域链查找。this的值只在进入上下文的时候进行一次确定。

  废话不多,先看一个板栗:

  代码如下:

  var test = function(){};

  test.prototype = {

  foo:"apple",

  fun:function(){

  this.foo="banana";

  }

  };

  var myTest = new test();

  myTest.fun();

  console.log(myTest.hasOwnProperty("foo")); //输出什么

  console.log(myTest.hasOwnProperty("fun")); //输出什么

  hasOwnProperty:是用来判断一个对象是否有你给出名称的属性或对象。不过需要注意的是,此方法无法检查该对象的.原型链中是否具有该属性,该属性必须是对象本身的一个成员。

  不知道看官们心里的答案是什么,正确的答案是true,false。

  代码如下:

  console.log(myTest.hasOwnProperty("foo"));

  console.log(myTest.hasOwnProperty("fun"));

  true

  false

  要弄明白为什么是这样,就必须要理解上面this所扮演的角色,所指代的对象。在《javascript语言精粹》一书中,指出了在javascript中一共有四种调用模式:

  1.方法调用模式

  2.函数调用模式

  3.构造器调用模式

  4.apply调用模式

  而在这些模式当中,对于如何初始化关键参数this上是存在不同差异的。

  方法调用模式

  当一个函数被保存为对象的一个属性时,我们称它为一个方法。当一个方法被调用时,this被绑定到该对象。注意加粗的这句是重点:

  代码如下:

  // 创建myObject。它有一个value属性和一个increment方法

  var myObject = {

  value: 0;

  increment: function(inc) {

  this.value += typeof inc ==='number'?inc:1; // 接受一个可选参数,如果不是数字,则默认为数字1

  }

  };

  myObject.increment();

  console.log(myObject.value); // 1

  myObject.increment(2); //传入数字2

  console.log(myObject.value); // 3

  这里,方法increment可以使用this去访问myObject对象,所以可以改变value的值。而且,this到对象的绑定发生在调用的时候。

  函数调用模式

  如果一个函数并非一个对象的属性时,那么它被当作一个函数来调用,此时,this被绑定到全局对象,书上说这是js语言设计的一个缺陷。倘若设计正确,当内部函数被调用的时,this应该仍然绑定到外部函数的this变量。抛开对语言设计的正确与否讨论,要当函数调用模式时this变量依旧绑定到该对象,有如下经典解决方案:

  代码如下:

  // 给myObject增加一个double方法