热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

带你深入理解js

文章目录

文章目录

      • 为什么需要Javascript引擎
      • 浏览器内核和JS引擎的关系
      • 变量环境 与 记录
      • 内存管理 和 闭包
      • JS的内存管理
      • JS的垃圾回收
      • 深入闭包
      • this指向
      • 箭头函数 arrow function
      • 认识arguments
      • 理解JvaScript纯函数
      • Javascript 柯里化
      • 组合函数
      • 其他内容
          • with语句
          • eval函数
      • 严格模式 strict Mode

TypeScript 会取代Javascript吗?

  1. TypeScript只是带来了类型的思维
    因为Javascript本身长期没有变量、函数参数等类型进行限制
    这可能给我们项目带来某种安全的隐患
  2. 在之后的Javascript社区中出现了一系列的类型约束方案
    2014年,Facebook推出来flow来对Javascript进行类型检查

3.Type源于Javascript,归于Javascript

为什么需要Javascript引擎

高级编程语言都需要转换成最终的机器指令来执行
事实上我们编写的Javascript无论交给浏览器或者Node执行,最后都是需要被CPU执行的
所以我们需要Javascript引擎帮助我们将Javascript代码翻译成CPU指令来执行

浏览器内核和JS引擎的关系

这里我们以WebKit为列,WebKit事实上由两部分组成:
WebCore:负责HTML解析、布局、渲染等等相关的工作
JavascriptCore:解析、执行Javascript代码

变量环境 与 记录

VO(Variable Object)变量对象 在最新的ECMA标准中,VO已经有另外一个称呼了变量环境 VE

GO(Clobal Object)全局对象,全局执行上下文

AO(Activation Objece)包括了函数执行上下文

内存管理 和 闭包

  1. 认识内存管理

在这里插入图片描述

JS的内存管理

Javascript会在定义变量时为我们分配内存
JS对于基本数据类型内存的分配会在执行时,直接在栈空间进行分配;
JS对于复杂数据类型内存的分配会在堆内存中开辟一块空间,并将这块空间的指针返回值变量引用

JS的垃圾回收

因为内存的大小是有限的,所以当内存不再需要的时候,我们需要对其进行释放,以便腾出更多的内存空间

垃圾回收的英文是 Garbage Collection 简称GC
对于那先不再使用的对象,我们都称之为是垃圾,它需要被回收,以释放更多的内存空间
而我们的语言运行环境,比如java的运行环境JVM,Javascript的运行环境js引擎都会内存垃圾回收器
垃圾回收器我们也简称GC,所以哎很多地方你看到 GC其实指的是垃圾回收器

深入闭包

在计算机科学中对闭包的定义(维基百科):
闭包(英语:Closure),又称词法闭包(Lexical Closure) 或函数闭包(function closures);
是在支持头等函数的编程语言中,实现词法绑定的一种技术;
闭包在实现上是一个结构体,它存储了一个函数和一个关联的环境(相当于一个符号查找表);
闭包跟函数最大的区别在于,当捕捉闭包的时候,它的自由变量会在捕捉时被确定,这样即使脱离了捕捉时的上下文,它也能照常运行

闭包的概念出现于60年代,最早实现闭包的程序时Scheme,那么我们就可以理解为什么Javascript中有闭包;
因为Javascript中有大量的设计是来源于Scheme的;
在这里插入图片描述

我们再来看一下MDN对Javascript闭包的解释:
一个函数和对其周围状态(lexical environment,词法环境) 的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包
也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域;
在Javascript中,每当创建一个函数,闭包就会在函数创建的同时被创建出来;

function foo() {
var name = 'why'
var age = 18
function bar() {
console.log('bar ',name)
}
return bar
}
var fun = foo()
fun()

总结:
一个普通的函数function,如果它可以访问外层作用于的自由变量,那么这个函数就是一个闭包;
从广义的角度来说:Javascript中的函数都是闭包;
从狭义的角度来说:Javascript中一个函数,如果访问了外层作用于的变量,那么它是一个闭包;

this指向

在全局作用域下:
浏览器:window
node环境:{}

箭头函数 arrow function

箭头函数是ES6 之后增加的一种编写函数的方法,并且它比函数表达式更加简洁;
箭头函数不会绑定this、arguments属性;
箭头函数不能作为构造函数来使用(不能和new一起来使用,会抛出错误)

认识arguments

arguments是一个对应于 传递给函数的参数的类(伪)数组(array-like) 对象

理解JvaScript纯函数

函数式编程中有一个非常重要的概念叫做纯函数,Javascript符合函数式编程的规范,所以也有纯函数的概念;

纯函数的维基百科定义:
在程序设计中,若一个函数符合以下条件,那么这个函数辈称为纯函数
此函数在相同的输入值时,需要产生相同的输出
函数的输出和输入值以外的其他隐藏信息或状态无关,也和由I/O设备产生的外部输出无关
改函数不能有语义上可观察的函数副作用,诸如 “触发事件”,使输出设备输出,或更改输出值以外物件的内容等
总结:
确定的输入,一定产生确定的输出;
函数在执行过程中,不能产生副作用;

副作用:

Javascript 柯里化

柯里化也是属于函数式编程里面一个非常重要的概念
维基百科解释:
在计算机科学中,柯里化(Currying) ,又译为卡瑞化 或加里化
是八接收多个参数的函数,变成接收一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数,而且返回结果的新函数
柯里化声称:如果你固定某些参数,你将得到接受余下参数的一个函数

总结:
只传递给函数一部分参数来调用它,让它返回一个函数区处理剩余的参数;
这个过程就称为柯里化

为什么需要柯里化:
在函数式编程中,我们其实往往希望一个函数处理的问题尽可能的单一,而不是将一大堆的处理过程交给一个函数来处理

function foo(x,y,c) {
return x + y + c
}
console.log(foo(10,20,30))
//柯里化
function sum(x) {
return function(y) {
return function(z) {
return x + y + z
}
}
}
var a = sum(10)(20)(30)
console.log(a )
//简化柯里化
var sum2 = x => y => z => {
return x + y + z
}
console.log(sum2(10)(20)(30 ))

组合函数

组合函数(Compose) 函数是在Javascript开发中一种对函数的使用技巧、模式:
比如我们现在需要对某个数据进行函数的调用,执行两个函数fn1 和 fn2,这两个函数是依次执行的
那么如果我们每次都需要进行两个函数的调用,操作上就会显示的重复
那么是否可以将这两个函数组合起来,自动依次调用呢?
这个过程就是对函数的组合,我们称之为组合函数(Compose Function)

其他内容

with语句

with 语句
+作用: 可以形成自己的作用域
不建议使用with语句 ,因为它可能是混淆错误和兼容性问题的根源

var obj2 = {name:'Tom',age:18,message:'obj2'}
// var message = "hello world"
function foo() {
function bar () {
with(obj2) {
console.log(message)
}
}
bar()
}
foo()

eval函数

eval是一个特殊的函数,它可以将传入的字符串当作Javascript 代码来运行

var strFn = 'var message = "Hello world"; console.log(message);';
eval(strFn)

不建议在开发中使用eval:
eval代码的可读性非常的差(代码的可读性是高质量代码的重要原则);
eval是一个字符串,那么有可能在执行的过程中辈可以篡改,那么可能会造成被攻击的风险;
eval的执行必须经过JS解释器,不能不被JS引擎优化;

严格模式 strict Mode

严格模式是一种具有限制性的Javascript模式,从而使代码隐式的脱离了"懒散(sloppy) 模式"
支持严格模式的浏览器在监测到代码中有严格模式时,会以更加严格的方式对代码进行监测和执行
严格模式通过抛出错误来消除一些原有的静默(silent)错误
严格模式让Js引擎周期执行代码时可以进行更多的优化(不需要对一些特殊的语法进行处理)

"use strict"; // 开启严格模式
var message = "hello world"
console.log(message)

严格模式限制
这里我们来说几个严格模式下的严格语法限制:
Javascript被设计为新手开发者更容易上手,所以有时候本来错误语法,被认为也是可以正常被解析的
但是在严格模式下,这种失误会被当成错误,以便可以快速的发现和修正

  1. 无法意外的创建全局变量

// 1. 意外创建全局变量
message = "Hello world"
console.log(message)
function foo() {
age = 20
}
foo()
console.log(age)

  1. 严格模式会时引起静默失败(silently fail ,注:不报错也没有任何效果)的赋值操作抛出异常

//默认静态错误
true.name ='xiaoluo';
NaN = 123

  1. 严格模式下试图删除不可删除的属性
  2. 严格模式不允许函数参数有相同的名称

// 不允许函数参数有相同的名称
function foo(x,y,x) {
console.log(x,y,x)
}
foo(10,20,30)

  1. 不允许0 的八进制语法

var num = 0o123 // 八进制
var num2 = 0x123 // 十六进制
console.log(num,num2)

  1. 在严格模式下, 不允许使用with

var obj2 = {name:'Tom',age:18,message:'obj2'}
with(obj2) {
console.log(message)
}

  1. 在严格模式下,eval 不再为上层引用变量

var strFn = 'var message = "Hello world"; console.log(message);';
eval(strFn)
console.log(message)

  1. 严格模式下,this绑定不会默认转成对象
    严格模式下,自执行函数会指向undefined

function foo() {
console.log(this) //undefined
}
foo()

推荐阅读
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • 浏览器作为我们日常不可或缺的软件工具,其背后的运作机制却鲜为人知。本文将深入探讨浏览器内核及其版本的演变历程,帮助读者更好地理解这一关键技术组件,揭示其内部运作的奥秘。 ... [详细]
  • Python 数据可视化实战指南
    本文详细介绍如何使用 Python 进行数据可视化,涵盖从环境搭建到具体实例的全过程。 ... [详细]
  • Framework7:构建跨平台移动应用的高效框架
    Framework7 是一个开源免费的框架,适用于开发混合移动应用(原生与HTML混合)或iOS&Android风格的Web应用。此外,它还可以作为原型开发工具,帮助开发者快速创建应用原型。 ... [详细]
  • 在PHP中如何正确调用JavaScript变量及定义PHP变量的方法详解 ... [详细]
  • 技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统
    技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统 ... [详细]
  • 本文深入探讨了 hCalendar 微格式在事件与时间、地点相关活动标记中的应用。作为微格式系列文章的第四篇,前文已分别介绍了 rel 属性用于定义链接关系、XFN 微格式增强链接的人际关系描述以及 hCard 微格式对个人和组织信息的描述。本次将重点解析 hCalendar 如何通过结构化数据标记,提高事件信息的可读性和互操作性。 ... [详细]
  • 探索Web 2.0新概念:Widget
    尽管你可能尚未注意到Widget,但正如几年前对RSS的陌生一样,这一概念正逐渐走入大众视野。据美国某权威杂志预测,2007年将是Widget年。本文将详细介绍Widget的定义、功能及其未来发展趋势。 ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • 在多线程并发环境中,普通变量的操作往往是线程不安全的。本文通过一个简单的例子,展示了如何使用 AtomicInteger 类及其核心的 CAS 无锁算法来保证线程安全。 ... [详细]
  • javascript分页类支持页码格式
    前端时间因为项目需要,要对一个产品下所有的附属图片进行分页显示,没考虑ajax一张张请求,所以干脆一次性全部把图片out,然 ... [详细]
  • 解决 Windows Server 2016 网络连接问题
    本文详细介绍了如何解决 Windows Server 2016 在使用无线网络 (WLAN) 和有线网络 (以太网) 时遇到的连接问题。包括添加必要的功能和安装正确的驱动程序。 ... [详细]
  • 基于Web的Kafka管理工具Kafkamanager首次访问Web界面的详细配置指南(附图解)
    首次访问Kafkamanager Web界面时,需要对Kafka集群进行配置。这一过程相对简单,用户只需依次点击【Cluster】>【Add Cluster】,按照提示完成相关设置即可。本文将通过图文并茂的方式,详细介绍每一步的配置步骤,帮助用户快速上手Kafkamanager。 ... [详细]
  • 在JavaWeb开发中,文件上传是一个常见的需求。无论是通过表单还是其他方式上传文件,都必须使用POST请求。前端部分通常采用HTML表单来实现文件选择和提交功能。后端则利用Apache Commons FileUpload库来处理上传的文件,该库提供了强大的文件解析和存储能力,能够高效地处理各种文件类型。此外,为了提高系统的安全性和稳定性,还需要对上传文件的大小、格式等进行严格的校验和限制。 ... [详细]
  • MySQL的查询执行流程涉及多个关键组件,包括连接器、查询缓存、分析器和优化器。在服务层,连接器负责建立与客户端的连接,查询缓存用于存储和检索常用查询结果,以提高性能。分析器则解析SQL语句,生成语法树,而优化器负责选择最优的查询执行计划。这一流程确保了MySQL能够高效地处理各种复杂的查询请求。 ... [详细]
author-avatar
谢超4444
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有