js 作为前端的中坚力量。那么 javascript 三座大山,你知道是哪些呢?

1️⃣ 作用域和闭包

作用域 指代码当前上下文,控制着变量和函数的可见性和生命周期。最大的作用是隔离变量,不同作用域下同名变量不会冲突。

作用域链 指如果在当前作用域中没有查到值,就会向上级作用域查询,直到全局作用域,这样一个查找过程所形成的链条就被称之为作用域链。

作用域可以堆叠成层次结构,子作用域可以访问父作用域,反之则不行。

作用域具体可细分为四种:全局作用域模块作用域函数作用域块级作用域

全局作用域: 代码在程序的任何地方都能被访问,例如 window 对象。但全局变量会污染全局命名空间,容易引起命名冲突。

模块作用域: 早期 js 语法中没有模块的定义,因为最初的脚本小而简单。后来随着脚本越来越复杂,就出现了模块化方案(AMD、CommonJS、UMD、ES6模块等)。通常一个模块就是一个文件或者一段脚本,而这个模块拥有自己独立的作用域。

函数作用域: 顾名思义由函数创建的作用域。闭包就是在该作用域下产生,后面我们会单独介绍。

块级作用域: 由于 js 变量提升存在变量覆盖、变量污染等设计缺陷,所以 ES6 引入了块级作用域关键字来解决这些问题。典型的案例就是 let 的 for 循环和 var 的 for 循环。

// var demo
for(var i=0; i<10; i++) {console.log(i);
}
console.log(i); // 10// let demo
for(let i=0; i<10; i++) {console.log(i);
}
console.log(i); //ReferenceError:i is not defined
复制代码

了解完作用域再来谈谈 闭包 函数A里包含了函数B,而函数B使用了函数A的变量,那么函数B被称为闭包或者闭包就是能够读取函数A内部变量的函数。

可以看出闭包是函数作用域下的产物,闭包会随着外层函数的执行而被同时创建,它是一个函数以及其捆绑的周边环境状态的引用的组合。换而言之,闭包是内层函数对外层函数变量的不释放

闭包的特征:

  • 函数中存在函数;
  • 内部函数可以访问外层函数的作用域;
  • 参数和变量不会被 GC,始终驻留在内存中;
  • 有内存地方才有闭包。

所以使用闭包会消耗内存、不正当使用会造成内存溢出的问题,在退出函数之前,需要将不使用的局部变量全部删除。如果不是某些特定需求,在函数中创建函数是不明智的,闭包在处理速度和内存消耗方面对脚本性能具有负面影响。

以下整理了闭包的应用场景:

// demo1 输出 3 3 3
for(var i = 0; i < 3; i++) {setTimeout(function() {console.log(i);}, 1000);
}
// demo2 输出 0 1 2
for(let i = 0; i < 3; i++) {setTimeout(function() {console.log(i);}, 1000);
}
// demo3 输出 0 1 2
for(let i = 0; i < 3; i++) {(function(i){setTimeout(function() {console.log(i);}, 1000);})(i)
}
复制代码
/* 模拟私有方法 */
// 模拟对象的get与set方法
var Counter = (function() {
var privateCounter = 0;
function changeBy(val) {privateCounter += val;
}
return {increment: function() {changeBy(1);},decrement: function() {changeBy(-1);},value: function() {return privateCounter;}
}
})();
console.log(Counter.value()); /* logs 0 */
Counter.increment();
Counter.increment();
console.log(Counter.value()); /* logs 2 */
Counter.decrement();
console.log(Counter.value()); /* logs 1 */
复制代码
/* setTimeout中使用 */
// setTimeout(fn, number): fn 是不能带参数的。使用闭包绑定一个上下文可以在闭包中获取这个上下文的数据。
function func(param){ return function(){ alert(param) }}
const f1 = func(1);setTimeout(f1,1000);
复制代码
/* 生产者/消费者模型 */
// 不使用闭包
// 生产者
function producer(){const data = new(...)return data
}
// 消费者
function consumer(data){// do consume...
}
const data = producer()// 使用闭包
function process(){var data = new (...)return function consumer(){// do consume data ...}
}
const processer = process()
processer()
复制代码
/* 实现继承 */
// 以下两种方式都可以实现继承,但是闭包方式每次构造器都会被调用且重新赋值一次所以,所以实现继承原型优于闭包
// 闭包
function MyObject(name, message) {this.name = name.toString();this.message = message.toString();this.getName = function() {return this.name;};this.getMessage = function() {return this.message;};
}
// 原型
function MyObject(name, message) {this.name = name.toString();this.message = message.toString();
}
MyObject.prototype.getName = function() {return this.name;
};
MyObject.prototype.getMessage = function() {return this.message;
};
复制代码

对于闭包的概念好像懂了但又好像缺少了啥?意犹未尽。我也曾也闭包中迷失,但是看完闭包的生命周期让我重新找回自己。

学完就来一波牛刀小试

function test(a, b){console.log(b);return {test: function(c) {return test(c,a);}}
}var a = test(100);a.test(101);a.test(102);
var b = test(200).test(201).test(202);
var c = test(300).test(301);c.test(302);// undefined  100  100
// undefined  200 201
// undefined  300 301
复制代码

2️⃣ 原型和原型链

有对象的地方就有 原型,每个对象都会在其内部初始化一个属性,就是prototype(原型),原型中存储共享的属性和方法。当我们访问一个对象的属性时,js引擎会先看当前对象中是否有这个属性,如果没有的就会查找他的prototype对象是否有这个属性,如此递推下去,一直检索到 Object 内建对象。这么一个寻找的过程就形成了 原型链 的概念。

理解原型最关键的是理清楚__proto__、prototype、constructor三者的关系,我们先看看几个概念:

  • __proto__属性在所有对象中都存在,指向其构造函数的prototype对象;prototype对象只存在(构造)函数中,用于存储共享属性和方法;constructor属性只存在于(构造)函数的prototype中,指向(构造)函数本身。
  • 一个对象或者构造函数中的隐式原型__proto__的属性值指向其构造函数的显式原型 prototype 属性值,关系表示为:instance.__proto__ === instance.constructor.prototype
  • 除了 Object,所有对象或构造函数的 prototype 均继承自 Object.prototype,原型链的顶层指向 null:Object.prototype.__proto__ === null
  • Object.prototype 中也有 constructor:Object.prototype.constructor === Object
  • 构造函数创建的对象(Object、Function、Array、普通对象等)都是 Function 的实例,它们的 __proto__ 均指向 Function.prototype。

看起来是不是有点乱??别慌!!一张图帮你整理它们之间的关系

相同的配方再来一刀

const arr = [1, 2, 3];
arr.__proto__ === Array.prototype; // true
arr.__proto__.__proto__ === Object.prototype; // true
Array.__proto__ === Function.prototype; // true
复制代码

3️⃣ 异步和单线程

JavaScript 是 单线程 语言,意味着只有单独的一个调用栈,同一时间只能处理一个任务或一段代码。队列、堆、栈、事件循环构成了 js 的并发模型,事件循环 是 JavaScript 的执行机制。

为什么js是一门单线程语言呢?最初设计JS是用来在浏览器验证表单以及操控DOM元素,为了避免同一时间对同一个DOM元素进行操作从而导致不可预知的问题,JavaScript从一诞生就是单线程。

既然是单线程也就意味着不存在异步,只能自上而下执行,如果代码阻塞只能一直等下去,这样导致很差的用户体验,所以事件循环的出现让 js 拥有异步的能力。

以上就是关于js三座大山的全部内容。什么?还不懂,告诉我ip地址我顺着网线过去教你!!

内容来自传送门

JavaScript 的三座大山相关推荐

  1. JavaScript的三座大山

    前言:这个题目是抄的,看着很有意思,就拿过用了,毕竟CV是程序员的基本功底嘛,顺带把图也拿过来了 作用域和闭包 这个几乎是天天在用的东西,可能有些人甚至不知道这个概念,但是用到过这种方法去解决某一些问 ...

  2. JavaScript的三座大山--(2)--作用域和闭包

    文章可能有点长,但 

  3. JavaScript的三座大山--(3)--单线程和异步

    就差最后一步啦,冲鸭

  4. JavaScript的三座大山--(1)--原型和原型链

    文章可能有点长,但 

  5. 长期维护更新,前端面试题整理

    网上找到的各种面试题整理,长期更新.大部分答案整理来自网络,有问题的地方,希望大家能指出,及时修改;技术更新迭代,也会及时更新 博客原地址: https://finget.github.io/2019 ...

  6. web前端面试高频考点——JavaScript 篇(一)【JS的三座大山 】 原型和原型链、作用域和闭包、异步

    系列文章目录 JavaScript 知识梳理,收录了web前端面试 95%以上 的高频考点,满满的干货.给你做一个高效的知识梳理,为你的面试保驾护航! 内容 参考链接 HTML & CSS 篇 ...

  7. JavaScript 三座大山

    原型与原型链及this 声明:下面说的对象是指 object Array Function 除 null 以外 1 任何对象 都可以做自由添加属性 var obj = {a:10, b:1} obj. ...

  8. 前端javascript总结笔记(一)--js的三座大山

    前言: 第一章为变量类型和计算. 第二章到第四章分别是原型与原型链,作用域及闭包,异步和单线程,这三个就是我们说的三座大山. 一.变量类型和计算 1:JS中使用typeof能得到哪些类型? 字符串(S ...

  9. javascript基础知识之三座大山

    三座大山:1.原型  原型链 2.作用域  闭包 3.异步  单线程 一.原型  原型链 知识点: (1)构造函数 (2)构造函数扩展 (3)原型规则和示例 二.作用域  闭包 知识点: (1)执行上 ...

最新文章

  1. html5 txt文件上传,JavaScript html5利用FileReader实现上传功能
  2. python 笔记(三) 断言(assert)
  3. 大型Javascript应用架构的模式(译文)
  4. win2003(sp2 x86)+iis6+php-5.3.5-Win32 配置
  5. ES6新特性_变量的解构赋值---JavaScript_ECMAScript_ES6-ES11新特性工作笔记006
  6. Myeclipse10如何进行代码提示和自动补全
  7. Chrome 谷歌浏览器查看网站证书
  8. 自组织映射(SOM)聚类分析Python第三方库实现<minisom>
  9. 正确的价值观和干部队伍引领华为走向长久成功
  10. 文档翻译——免费版(word格式、pdf格式)
  11. 计算机模拟圣彼得堡游戏
  12. 纯CSS实现三角形图标
  13. 49 把字符串转换成整数
  14. pyqt5显示日期与时间
  15. SAP BDC数据批量导入功能
  16. collections
  17. 【Unet系列】(三)Unet++网络
  18. 天下文章一大抄看你会抄不会抄devGridView凭证金额录入(万仟百拾元)
  19. 使用Markdown语言在博客的文章中添加视频
  20. 小程序开发系列之基础部分-开发工具

热门文章

  1. 高通骁龙670处理器曝光:10nm工艺,性能完爆骁龙660
  2. Spring事务处理浅析
  3. 二维数组转对象+实战
  4. @程序员,你哄女朋友要是有写代码那么6,你早就脱单了
  5. 细数Android开发者的艰辛历程,2年以上经验必看
  6. 多媒体内容审核, 打造安全合规的UGC新生态
  7. 抖音直播运营的5个要点,15个操作步骤!
  8. C语言:指针一(基础概念)
  9. 因为修改系统设置导致edge浏览器打不开的最快解决办法
  10. xp系统什么梗_2019年还用XP是怎样的体验?告诉你XP凉得有多透