JavaScript中的作用域与闭包、原型与原型链、异步与单线程

 更新时间:2024年02月17日 16:58:18   投稿:yin  
JavaScript的三座大山指的是:作用域和闭包、原型和原型链、异步与单线程,这些概念在日常的开发工作中经常被提及,并对我们理解和编写高质量的JavaScript代码至关重要

一、作用域与闭包

作用域和闭包是JS中的两个重要概念,了解其原理可以方便我们更好地理解JS的一些细节。作用域描述了程序源代码在何处可以访问变量、函数等标识符,而闭包则是指有权访问另一个函数作用域内变量的函数。

1. 作用域

作用域分为全局作用域和局部作用域。全局作用域是定义在最外层,所有的内容代码都可以访问它;而局部作用域则是函数内部定义的变量,在函数执行完之后会被销毁。

我们可以通过块作用域和函数作用域来更好地控制变量的作用域。

//块作用域
if (true) {
  let x = 1;
}
console.log(x); //ReferenceError: x is not defined,x只能在if块作用域内访问
//函数作用域
function foo() {
  let y = 2;
}
console.log(y); //ReferenceError: y is not defined,y只能在foo函数作用域内访问

关于作用域的重要性在于可以避免变量的命名冲突、保护变量不被误修改以及提供更好的可维护性。

2. 闭包

闭包实际上指的是函数和声明该函数的词法环境的组合,即函数体内的引用环境。在函数内定义的变量以及函数参数都是在词法环境中声明的,因此都可以通过闭包被访问。闭包可以实现一些高阶函数的功能,比如计数器、函数记忆、数据缓存等。

function counter() {
  var count = 0;
  function add() {
    count++;
    console.log(count);
  }
  return add;
}
var counter1 = counter();
var counter2 = counter();
counter1();// 1
counter1();// 2
counter2();// 1
counter2();// 2

上述代码实现了多个计数器的功能,而这正是闭包的作用。

二、原型与原型链

原型是JS中许多复杂特性的基础,构成了JS中的面向对象机制。它是JS中每个对象都拥有的一个内置的属性,通过该属性可实现属性继承以及方法的共享。

1. 原型

在JS中,每个对象都有一个内部的[[prototype]]属性,也称为原型,指向他的原型对象。通过原型,对象可以继承原型对象的属性和方法。

let emptyObj = {};
console.log(emptyObj.__proto__); //Object.prototype

在JS中,每个对象都是由构造函数创建的。程序可以自定义构造函数,以此来创建自己的对象。如果在构造函数中指定了一个prototype对象,那么所有的实例都会继承该prototype对象的属性和方法。

function Person(name) {
  this.name = name;
}
Person.prototype.sayHi = function () {
  console.log(`Hi, my name is ${this.name}`);
};
let person1 = new Person('张三');
person1.sayHi(); //Hi, my name is 张三
let person2 = new Person('李四');
person2.sayHi(); //Hi, my name is 李四

2. 原型链

原型链是实现JS中继承的基础。对象的原型可能是其他对象,而这些对象同样具有原型。这些关系被称为原型链。如果一个对象在它的原型链上找不到特定的属性或者方法,那么它会继续查找它的原型链。在找到匹配的方法或属性之前,会沿着原型链逐级查找。

let emptyObj = {};
console.log(emptyObj.toString()); //[object Object],toString方法被Object.prototype继承
console.log(emptyObj.__proto__); //Object.prototype
console.log(emptyObj.__proto__.__proto__); //null,原型链到达了Object.prototype的上层

原型链是JS中非常重要的概念,对了解继承、原型、对象、构造函数等都具有很大的帮助。

三、异步与单线程

JS是单线程的语言,也就是说JS引擎中只有一个线程在执行任务。如果任务比较耗时,会导致线程阻塞,即后续任务无法执行。

1. 异步

为了解决单线程带来的问题,JS引入了异步编程的方式。JS中的异步函数通常是由回调函数、Promise、Generator、async/await等方式实现。

回调函数

回调函数是最常见的异步实现方式,当异步操作完成时,将调用一个函数,以通知应用程序。

function loadData(callback) {
  setTimeout(() => {
    callback('This is the data');
  }, 2000);
}
function loadDataCallback(data) {
  console.log(data);
}
loadData(loadDataCallback); //2秒后输出This is the data

Promise

Promise是ES6引入的一个新特性,它是一种更加优雅的异步实现方式。Promise支持链式调用、错误捕获等功能。

function loadData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('This is the data');
    }, 2000);
  });
}
loadData().then((data) => {
  console.log(data);
});

2. 事件循环

JS采用事件循环机制,它会不断地检查任务队列,如果队列中有任务,就将任务取出来执行。

事件循环提供了异步编程的基础,多个异步任务可以并行执行,并且不会发生阻塞,这使得JS具有高并发性能。

console.log('start');
setTimeout(() => {
  console.log('2s later');
}, 2000);
console.log('end');
//输出start,end
//2s后输出2s later

学会异步编程,是JS开发中非常重要的一部分。

四、总结

JavaScript的三座大山指的是:作用域和闭包、原型和原型链、异步与单线程,这些概念在日常的开发工作中经常被提及,并对我们理解和编写高质量的JavaScript代码至关重要。到此这篇关于JavaScript中的作用域与闭包、原型与原型链、异步与单线程的文章就介绍到这了,更多相关JavaScript的三座大山内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于BootStrap的图片轮播效果展示实例代码

    基于BootStrap的图片轮播效果展示实例代码

    这篇文章主要介绍了基于BootStrap的图片轮播效果展示实例代码的相关资料,需要的朋友可以参考下
    2016-05-05
  • JavaScript Array实例方法flat的实现

    JavaScript Array实例方法flat的实现

    flat() 方法用于将一个嵌套多层的数组进行扁平,返回新数组,它不会改变原始数组, flat 方法在处理多维数组时非常有用,它可以让数组操作变得更加灵活和简洁,本文给大家介绍了JavaScript Array实例方法flat的实现,需要的朋友可以参考下
    2024-03-03
  • JS实现监控微信小程序的原理

    JS实现监控微信小程序的原理

    这篇文章主要介绍了JS实现监控微信小程序的原理,本文通过实例代码相结合的形式给大家介绍的非常详细,需要的朋友可以参考下
    2018-06-06
  • 百度地图JavascriptApi Marker平滑移动及车头指向行径方向

    百度地图JavascriptApi Marker平滑移动及车头指向行径方向

    本文主要介绍了百度地图JavascriptApi Marker平滑移动及车头指向行径方向的相关知识。具有很好的参考价值。下面跟着小编一起来看下吧
    2017-03-03
  • 微信小程序实现通讯录列表展开收起

    微信小程序实现通讯录列表展开收起

    这篇文章主要为大家详细介绍了微信小程序实现通讯录列表展开收起,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11
  • 基于ionic实现下拉刷新功能

    基于ionic实现下拉刷新功能

    这篇文章主要为大家详细介绍了基于ionic实现下拉刷新功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • 深入了解JavaScript中的二进制操作及位掩码应用

    深入了解JavaScript中的二进制操作及位掩码应用

    在JavaScript中,二进制操作可以说是一项非常强大和有用的技能,尤其是在处理数据和位掩码时,它们是不可或缺的,本文将介绍JavaScript中的二进制操作,包括什么是二进制以及如何在JavaScript中进行二进制操作
    2023-06-06
  • JS中移除非数字最多保留一位小数

    JS中移除非数字最多保留一位小数

    这篇文章主要介绍了JS中移除非数字最多保留一位小数的实现代码,文章给大家提到了js处理数字保留2位小数,强制保留2位小数不够补上.00的完整代码,感兴趣的朋友一起看看吧
    2018-05-05
  • JavaScript优化以及前段开发小技巧

    JavaScript优化以及前段开发小技巧

    随着前端技术的发展,前端业务越来越繁重,这大大增加了JS代码量。因此,要提高Web的性能,我们不仅需要关注页面加载的时间,还要注重在页面上操作的响应速度。那么,接下来我们讨论几种能够提高JavaScript效率的方法。
    2017-02-02
  • js iframe跨域访问(同主域/非同主域)分别深入介绍

    js iframe跨域访问(同主域/非同主域)分别深入介绍

    js跨域是个讨论很多的话题。iframe跨域访问也被研究的很透了,本文今天就叨叨两句,感兴趣的朋友可以了解下,就当巩固知识了,希望本文对你有所帮助
    2013-01-01

最新评论