JavaScript 中的 Hoisting (变量提升和函数声明提升)

如何将 函数声明 / 变量 “移动” 到作用域的顶部。

术语 Hoisting(提升) 在很多 JavaScript 博文中被用来解释标识符的解析。其实 Hoisting(提升) 这个词是用来解释 变量 和 函数声明 是如何被提升到 函数或全局 作用域顶部的。你在任何的 JavaScript 文档中找不到这个术语,我们说的 Hoisting(提升) 只是使用了其字面含义来做个比喻。

如果你已经对 JavaScript 作用域工作原理有基本的了解,那么更深入的了解 Hoisting(提升) 有助于你建立更强大的基础知识。(愚人码头注:作为 JavaScript 中的一个总要概念,变量提升和函数声明提升经常在前端开发面试时被问及,或者在前端开发笔试题中出现。可见了解 Hoisting(提升) 的重要性。)

为了更好地理解基础知识,让我们来回顾一下 “Hoisting(提升)” 到底意味着什么。另外,给你一个提醒,JavaScript 是一种解释性语言,这不同于编译性语言,这意味着JS代码是逐行执行的。 继续阅读

深入理解JavaScript中的作用域和上下文

在本教程中,我们将深入学习 JavaScript 中作用域(Scope)的一切。 所以,来吧。

介绍

JavaScript中有一个被称为作用域(Scope)的特性。虽然对于许多新手开发者来说,作用域的概念并不是很容易理解,我会尽我所能用最简单的方式来解释作用域。理解作用域将使你的代码脱颖而出,减少错误,并帮助您使用它强大的设计模式。

什么是作用域(Scope)?

作用域是在运行时代码中的某些特定部分中变量,函数和对象的可访问性。换句话说,作用域决定了代码区块中变量和其他资源的可见性。

为什么说作用域是最小访问原则?

那么,为什么要限制变量的可见性呢,为什么你的变量不是在代码的任何地方都可用呢?一个优点是作用域为您的代码提供了一定程度的安全性。计算机安全的一个常见原则是用户应该一次只能访问他们需要的东西。 继续阅读

JavaScript 核心概念之作用域和闭包

相信大家已经阅读了很多关于作用域和闭包文章,我也一样。作用域和闭包是 JavaScript 中的关键概念之一。当我阅读了《高性能的JavaScript》这本书后,我才完全理解这两个概念。所以今天强烈推荐这本书中的解释,并与其他开发人员分享。

作用域

下面会提到几个概念:

  • 函数对象的[[scope]]属性
  • Scope Chain(作用域链)
  • Execution Context(运行期上下文)
  • Activation Object(激活对象)

函数对象的[[scope]]属性

JavaScript 中每个函数都都表示为一个函数对象(函数实例),既然是对象,就有相关的属性和方法。除了正常的属性,函数对象具有仅供 JavaScript 引擎内部使用,但不能通过代码访问的一系列内部属性。这些属性中,其中一个就是 [[scope]] 属性。 继续阅读

ES2015 中的箭头函数和词法 this

箭头函数是使用=>语法对函数定义的简写。它们在语法上类似于 C#,Java 8 和 CoffeeScript 中的相关特性。它们支持表达式(Expression bodies)和函数体(Statement bodies)。与函数不同,箭头函数与其上下文代码共享相同的词法this(愚人码头注:箭头函数并没有自己的this,它的this是派生而来的,根据“词法作用域”派生而来)。如果箭头函数在另一个函数体内,它共享其父函数的 arguments 变量。

// 使用表达式(Expression bodies)
var odds = evens.map(v => v + 1);
var nums = evens.map((v, i) => v + i);

// 使用函数体(Statement bodies)
nums.forEach(v => {
  if (v % 5 === 0)
    fives.push(v);
});

// 词法`this`
var bob = {
  _name: "Bob",
  _friends: [],
  printFriends() {
    this._friends.forEach(f =>
      console.log(this._name + " knows " + f));
  }
};

// 词法 arguments
function square() {
  let example = () => {
    let numbers = [];
    for (let number of arguments) {
      numbers.push(number * number);
    }

    return numbers;
  };

  return example();
}

square(2, 4, 7.5, 8, 11.5, 21); // returns: [4, 16, 56.25, 64, 132.25, 441]

继续阅读