资讯专栏INFORMATION COLUMN

JavaScript的this和作用域

wapeyang / 1356人阅读

摘要:本文主要讨论一下的作用域和关键字。另外的作用域就只有局部作用域了。在里一般就是一个方法内部的作用域。你应该尽量少的往全局作用域添加属性。它的值和方法的调用方式有很大的关系。比如使用一个通用的事件监听器来处理一系列的有相似事件的元素。

本文主要讨论一下JS的作用域和this关键字。作用域,就是你的方法或者变量可访问的区域,是他们执行的上下文。如果你见过这样的代码:

function someFunc() {
  var _this = this;
  something.on("click", function() {
    console.log(_this);
  });
};

你就会很好奇为什么要用this赋值给一个变量_this呢?你看完这篇文章就会清楚这个问题的答案了。

第一种作用域叫做全局作用域(Global Scope)这很容易定义,如果一个方法、变量是全局作用域的,那么它就可以从任何的地方访问到。在浏览器里,全局作用域就是window对象。所以,如果你的代码里有:

var x = 9;

你其实是在给window.x赋值为9(在浏览器里运行的时候)。如果你喜欢的话,也可以写成window.x = 9,当然这不是很必要。全局作用域对象的属性可以在代码的任何地方访问到。

另外的作用域就只有局部作用域了。在JavaScript里一般就是一个方法内部的作用域。比如:

function someFunction() {
  var x = 5;
}
console.log(x); // undefined

变量x是在方法内部初始化的,那么就只能在方法内部访问。

一些需要注意的地方

如果你声明了一个变量,而且在声明的时候忘记使用var关键字。那么,这个变量自动被置为全局变量。比如:

function someFunction(){
  x = 5;
}

// 执行一个这个方法,完成x的全局设置
someFunction();

console.log(x); // 5

这是一个非常差的实践。你应该尽量少的往全局作用域添加属性。这也是为什么你会经常看到一些库,比如jQuery会这么干:

(function() {
  var jQuery = {/*全部的方法都在这里*/};
  window.jQuery = jQuery;
})();

把全有的属性、方法都放在一个方法里。然后立刻执行这个方法就会把全部的属性和方法都绑定在了局部作用域里。最后把jQuery对象绑定到全局作用域,间接的把之前定义的属性和方法都暴露出来方便调用。显然我大量的减少了jQuery的代码,但是这就是jQuery代码如何工作的。

由于局部作用域只有通过方法的定义来实现。任何在一个方法内部定义的方法都可以访问外部方法里定义的变量。比如:

function outer() {
  var x = 5;
  function inner() {
    console.log(x); // 5
  }

  inner();
}

但是outer()方法不可以访问inner()方法定义的任何变量。

function outer() {
  var x = 5;
  function inner() {
    console.log(x); // 5
    var y = 100;
  }

  inner();
  console.log(y); // undefined
}

这很容易理解。但是当我们试图要探究this关键字的时候就又变得复杂了。我相信很多人都遇到过这样的问题:

${"myLink"}.on("click", function() {
  console.log(this);  // 指向myLink

  $.ajax({
    // 设置ajax相关
    success: function() {
      console.log(this);  // 指向的是全局对象。 ???
    }
  });
});

this是在方法执行的时候自动赋值的变量。它的值和方法的调用方式有很大的关系。比如:

function foo() {
  console.log(this);  // global object
}

theApp = {};
theApp.foo = function() {
  console.log(this);  // 指向theApp对象
}

var link = doeument.getElementById("myLink");
link.addEventListener("click", function() {
  console.log(this); // 指向link
});

MDN对第三个例子的解释非常到位:

事件的this总是指向出发这个事件的元素对象。比如使用一个通用的事件监听器来处理一系列的有相似事件的元素。当使用addEventListener把一个方法添加到一个元素的事件处理器的时候,这个方法的this值就被改变了。注意,this的值是从调用者里传给方法的。

这么做:$("myLink").on("click", function() {})意味着link被点击的时候方法就会执行。由于这个方法是处理link的事件的,所以this的值就是这个link元素。

在Ajax请求的success回调方法只是一个普通的方法。所以,当它被调用的时候this指向的是全局对象。任何对象,不是对象方法或者事件的时候会遇到的情况。

上面的原因也就是你在很多地方看到var _this = this;或者var that = this;的原因。来看一个例子:

$("myLink").on("click", function() {
  console.log(this); //指向myLink
  var _this = this;
  $.ajax({
    // ajax设置
    success: function() {
      console.log(this);  // 指向全局对象
      console.log(_this); // 指向myLink
    }
  });
});

原文地址:https://javascriptplayground....

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/92634.html

相关文章

  • 谈谈javascript语法里一些难点问题(二)

    摘要:讲作用域链首先要从作用域讲起,下面是百度百科里对作用域的定义作用域在许多程序设计语言中非常重要。原文出处谈谈语法里一些难点问题二 3) 作用域链相关的问题 作用域链是javascript语言里非常红的概念,很多学习和使用javascript语言的程序员都知道作用域链是理解javascript里很重要的一些概念的关键,这些概念包括this指针,闭包等等,它非常红的另一个重要原因就...

    Enlightenment 评论0 收藏0
  • 十分钟快速了解《你不知道 JavaScript》(上卷)

    摘要:最近刚刚看完了你不知道的上卷,对有了更进一步的了解。你不知道的上卷由两部分组成,第一部分是作用域和闭包,第二部分是和对象原型。附录词法这一章并没有说明机制,只是介绍了中的箭头函数引入的行为词法。第章混合对象类类理论类的机制类的继承混入。 最近刚刚看完了《你不知道的 JavaScript》上卷,对 JavaScript 有了更进一步的了解。 《你不知道的 JavaScript》上卷由两部...

    赵春朋 评论0 收藏0
  • [译] 你想知道关于 JavaScript 作用一切

    摘要:原文链接原文作者你想知道的关于作用域的一切译中有许多章节是关于的但是对于初学者来说甚至是一些有经验的开发者这些有关作用域的章节既不直接也不容易理解这篇文章的目的就是为了帮助那些想更深一步学习了解作用域的开发者尤其是当他们听到一些关于作用域的 原文链接: Everything you wanted to know about JavaScript scope原文作者: Todd Mott...

    Flands 评论0 收藏0
  • JavaScript 闯关记》之作用闭包

    摘要:作用域和闭包是最重要的概念之一,想要进一步学习,就必须理解作用域和闭包的工作原理。全局和局部作用域的关系在函数体内,局部变量的优先级高于同名的全局变量。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。 作用域和闭包是 JavaScript 最重要的概念之一,想要进一步学习 JavaScript,就必须理解 JavaScript 作用域和闭包的工作原理。 作用域 任何...

    Jacendfeng 评论0 收藏0
  • 深入javascript——作用闭包

    摘要:注意由于闭包会额外的附带函数的作用域内部匿名函数携带外部函数的作用域,因此,闭包会比其它函数多占用些内存空间,过度的使用可能会导致内存占用的增加。 作用域和作用域链是javascript中非常重要的特性,对于他们的理解直接关系到对于整个javascript体系的理解,而闭包又是对作用域的延伸,也是在实际开发中经常使用的一个特性,实际上,不仅仅是javascript,在很多语言中都...

    oogh 评论0 收藏0
  • 这一次,我们换种姿势学习 javascript

    摘要:操作符或调用函数时传入参数的操作都会导致关联作用域的赋值操作。此外可以使用和来设置对象及其属性的不可变性级别。忽视这一点会导致许多问题。使用调用函数时会把新对象的属性关联到其他对象。 前言 《你不知道的 javascript》是一个前端学习必读的系列,让不求甚解的JavaScript开发者迎难而上,深入语言内部,弄清楚JavaScript每一个零部件的用途。本书介绍了该系列的两个主题:...

    zone 评论0 收藏0

发表评论

0条评论

wapeyang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<