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的三座大山内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
element UI中在 el-select 与 el-tree 结合组件实现过程
项目上实现某个功能,使用到了 el-select 和 el-tree 组合实现,记录下两者结合的实现过程,对 el-select 与 el-tree 结合组件实现过程感兴趣的朋友跟随小编一起看看吧2023-02-02阻止JavaScript事件冒泡传递(cancelBubble 、stopPropagation)
阻止JavaScript事件冒泡传递(cancelBubble 、stopPropagation)...2007-05-05基于JavaScript实现高德地图和百度地图提取行政区边界经纬度坐标
本文给大家介绍javascript实现高德地图和百度地图提取行政区边界经纬度坐标的相关知识,本文实用性非常高,代码简单易懂,需要的朋友参考下吧2016-01-01微信小程序中this.data与this.setData的区别详解
这篇文章主要给大家介绍了关于微信小程序中this.data与this.setData区别的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起看看吧2018-09-09JS组件系列之Bootstrap table表格组件神器【二、父子表和行列调序】
本文结合Bootstrap table的父子表和行列调序的用法再来介绍下它稍微高级点的用法。对bootstrap表格组件相关知识感兴趣的朋友一起学习吧2016-05-05《javascript设计模式》学习笔记七:Javascript面向对象程序设计组合模式详解
这篇文章主要介绍了Javascript面向对象程序设计组合模式,结合实例形式分析了《javascript设计模式》中Javascript面向对象组合模式相关概念、原理、定义、用法及操作注意事项,需要的朋友可以参考下2020-04-04微信 jssdk 签名错误invalid signature的解决方法
这篇文章主要介绍了微信 jssdk 签名错误invalid signature的解决方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2019-01-01
最新评论