JavaScript语言的灵魂是编程思想和语言自由的特色规则, 掌握了这些之后才能在规则之下产出良性的代码,任何前端的优秀框架都是通过JavaScrpt一点点搭建起来的,框架中带有的神奇功能没有能摆脱原始变成语言的,所以学好基础是王道
静态类型
JavaScript是一门动态类型的编程语言,他本身并不具备静态类型的能力,动态类型语言虽然在编程上工作量小代码简介,其本身存在部分弊端,这部分弊端主要体现在如下案例中
var a = 0
function test() {
a = 'hello'
}
test()
console.log(a)
a++
console.log(a)
在当前案例中,由于JavaScript并没有类型约束的能力,所以a在定义时我们希望他本身的类型是number,但是在test函数执行时,a的类型变成了string,后面使用a++时a就无法实现正常的计数能力而返回NaN。
在工程化开发时复杂的模块化代码和业务代码会让刚才的情况变得更加复杂,所以在这个时候,程序员们希望JavaScript据北京台语言的特性,也就是程序员希望JavaScript存在类型约束能力,不过JavaScript对于单个变量的约束是比较困难的,所以可以临时将代码编程这个样子
let obj = {
num: 123
}
let objProxy = new Proxy(obj, {
set (target, key, value) {
let type = Object.prototype.toString.call(vall).substring(8).replace(']', '')
console.log(type, key, value)
if (key === 'num' && type != 'Number') {
throw(`TypeError:${type} is not allowed`)
} else {
target[key] = val
}
},
get (target, key) {
return target[key]
}
})
通过简单的编程手段,可以借助代理对象对Object对象的key实现类型约束,这种方式在纯JavaScript开发中可以作为类型约束的解决方案,但是站在合理性和性能等多方面考虑时,JavaScript的类型约束器势必会占大量的应用运行内存,本来简单的赋值操作,会触发所有的属性都进行一次类型检测,这导致了在JavaScript这门语言上做类型约束产生了很多弊端,这时Flow和TypeScript等方案陆续出现。
Flow和TypeScript 等技术都是为了解决类型约束而问世的,首先要排除一个误区,Flow和TypeScript本身并不是在runtime层面解决的类型约束,所以他们并非单独的编程语言,很多程序员会下意识的认为这两种技术是单独存在的运行环境可以在浏览器中工作的编程语言,但实际上他们的工作流程是将类型约束提升到了compiler层,真正落地在runtime中的仍然是JavaScript语言,所以这两种技术的类型约束是在程序运行前进行的,并不会影响程序本身的执行性能。
JavaScript的不可变性
基本类型的不可变性
基本类型(number、string、boolean、null、undefined)的值已经是不可变的了;你无法做任何事类改变他们
2 = 2.5 // 不合法 也没有意义
然而,JS确实有一种特殊的行为,使他看起来允许修改这样的基本类型值“封箱”。当你访问特定基本类型上的属性时-- 具体说是number、string和boolean JS在底层自动将这个值包装也就是封箱,她在对应的对象中分别是Number、String、Booean
var x = 2
x.length = 4
x // 2
x.length // undefined
数字一般没有length属性可用,所以设置x.length = 4 是在试图添加一个新属性,而且它无声的失败了;继续持有基本数据类型2
但是如果除了潜在的使读者糊涂外没有其他原因,JS允许x.length=4运行这件事看起来根本就是个麻烦。好消息是,如果你使用了strict模式,这样的语句将抛出一个错误。
var x = new Number(2)
x.length = 4 // 可以工作
var s = 'hello'
s[1] = 'E'
s.length = 10 // s: 'hello',s.length = 5
重新赋值
如何描述一个常量是什么?
“一个不能改变的值”,“一个不能被改变的变量”。这些大约都是正确答案的邻居,但不是十分正确。一个常量的准确定义应该是:一个不能被重新赋值的变量
这种吹毛求疵很重要,因为他明确了一个常量实际上与值没有关系,除了无论一个常量持有什么值,这个变量都不能再被赋值为任何其他值。但他没说关于值本省性质的任何事情。
冻结
有一种即便宜又简单的方法可以将一个可变的对象/数组/函数变为一个(某种意义上的)不变值
var x = Object.freeze([1,2,3,4,5])
但是要注意 Object.freeze是浅层的freeze 不会递归
JavaScript的异步编程
- 单线程异步模型(JavaScript总是体单线程的程序特性,同一时间节点并不能做多个事情)
- 同步任务永远在异步任务前进行(同步任务先行策略,严格区分同步异步)
- 异步任务在进行的过程中是通过统一队列排列执行的,所以存在任务间的阻塞
- 异步任务氛围宏任务和微任务,宏任务是全局异步任务由同一个队列进行编排,微任务是归属不同任务的子任务,每个阶段的异步任务归属他们节点的宏任务
- 单线程异步模型与多线程完全是两个概念
- 并发和并行的区别
总结
基于以上,我们要确认一个统一的思想就是,作为业务开发者,重点是在各种框架的运用上,而作为架构师和技术专家,重点反而在基础编程思想和基础编程技术上。只有基本功扎实并且有国人思想的人才能构建出令大部分程序员折服的框架,并且能为现代应用开发在技术产出环节上帮助到更多的开发者,这个就是架构师、技术专家的作用。