返回

JS原型链、this指向、变量提升与覆盖一网打尽!

前端

JavaScript中有一个非常重要的概念叫做作用域 ,作用域决定了变量在程序中可以被访问的范围,而变量提升和变量覆盖则是作用域的两种体现形式。

变量提升 是指变量在使用之前会被提升到其所在的作用域的顶部。这意味着变量可以在声明之前被使用,但它的值是undefined。变量覆盖则是指在同一个作用域内,使用相同的变量名声明一个新的变量,这会覆盖掉之前声明的变量。

this 指向是JavaScript中另一个重要的概念,它代表着当前执行代码的对象。在大多数情况下,this指向当前函数的调用者,但在某些情况下,this指向可能会发生变化,比如使用call()、apply()和bind()方法时。

原型链 是JavaScript中用来实现继承的一种机制。每个对象都有一个原型对象,原型对象也有自己的原型对象,如此循环下去,直到遇到null。当访问一个对象的属性或方法时,JavaScript会沿着原型链向上查找,直到找到该属性或方法。如果找不到,则会返回undefined。

闭包 是指能够访问其父函数作用域的变量的函数。闭包通常用于保存一些状态信息,或者在父函数执行完后仍能访问父函数中的变量。

这些概念环环相扣,互相作用,构成了JavaScript运行机制的基础。理解这些概念,对于深入理解JavaScript至关重要。

下面通过一些例子来进一步说明这些概念。

  1. 变量提升
console.log(a); // undefined
var a = 10;

在这个例子中,变量a在使用之前被提升到了全局作用域的顶部,因此在声明之前就可以使用它,但它的值是undefined。

  1. 变量覆盖
var a = 10;
var a = 20;
console.log(a); // 20

在这个例子中,第二个var a覆盖掉了第一个var a,因此console.log(a)输出的是20。

  1. this 指向
function Person(name) {
  this.name = name;
}

Person.prototype.sayHello = function() {
  console.log(`Hello, my name is ${this.name}`);
};

var person1 = new Person('John');
person1.sayHello(); // Hello, my name is John

var person2 = new Person('Jane');
person2.sayHello(); // Hello, my name is Jane

在这个例子中,this指向当前正在执行的Person对象。因此,person1.sayHello()输出的是"Hello, my name is John",而person2.sayHello()输出的是"Hello, my name is Jane"。

  1. 原型链
function Person(name) {
  this.name = name;
}

Person.prototype.sayHello = function() {
  console.log(`Hello, my name is ${this.name}`);
};

var person1 = new Person('John');

console.log(person1.name); // John
console.log(person1.sayHello()); // Hello, my name is John

在这个例子中,person1的原型对象是Person.prototype,因此person1可以访问Person.prototype中的属性和方法。

  1. 闭包
function outerFunction() {
  var a = 10;

  function innerFunction() {
    console.log(a); // 10
  }

  return innerFunction;
}

var innerFunction = outerFunction();

innerFunction(); // 10

在这个例子中,innerFunction是一个闭包,它可以访问其父函数outerFunction的作用域,因此它可以访问变量a。

这些例子只是JavaScript中这些概念的几个简单应用,实际上,这些概念的应用非常广泛,在实际开发中经常会遇到。