疾风式全栈教程(9)-语法大班(草稿预览)

有没有发现一个问题,我们之前一直是在浏览器里运行代码,原来说的高大上的node呢,自从装上之后一次都还没用过呢.

哈哈 那我们就开始用一用.其实他们都是运行js的环境,js的标准语法是一致的,只是在于环境中提供的内容不太一样.

还是用我们之前写的js文件,这次不再放到script标签里了,而是打开cmd,用node运行.

所以node就是一个运行js文件的地方.

但是js文件多了,就会有一个如何管理的问题.以前我们在页面上引入script,一个页面引入几十个js文件,就不得了了,但是node这,可能要管理成千上万个js文件,都像script一样找路径,引入,运行,工作量就太大了.

所以就有了包和模块的机制.

什么是模块呢,就是把一大块东西分成一小块一小块的.和切菜 吃饭是一个道理.大块的不好处理,我们会用刀或者用牙分成小块,再吃下去.

我们这里的模块,简单的说就是js文件.

但是,由于node出现的晚,之前js一直是基本只在网页上通过script标签来用,也没有什么模块化的机制.node算是开了个头,但是却没有成为统一的标准,es6出现的更晚,虽然理论上是官方标准,实际情况却是还在和之前其他的习惯用法混合并用中.这也就是js现在所处的环境,感觉比较混乱.希望将来能慢慢规范和统一吧.

node之前使用的模块化机制是,用require导入模块,用module.export导出模块.而es6标准的模块化机制是用import导入,用export导出.具体写法大家可以搜索网上的文章和代码.重要的是,我们要明白,在一个js文件里定义的内容,如果没有声明导出的话,在其他文件里是无法使用的.即使导出了,其他文件要想使用,也必须先声明导入.

其实也没有什么,想用的话,先声明两下而已.不过这里其实代表了计算机世界里很多类似这种方式的机制,也就是被称为作用域的概念.比如,之前我们说的,要使用一个新名字,必须要先声明赋值,然后才能使用.其实通过先后顺序,也定义了一个范围.还有一个规定叫块级作用域,也就是大括号限定的的范围,大括号里定义的名称,大括号外是不能访问的.函数一般也有大括号,也划定了一个作用域.

之前的js还有一个坑就是var不受块级作用域限制,不过我们很少用到var.都用const或let就可以了.


现在可以按照模块的方式来管理js文件了.可是似乎还没有解决大量js文件管理困难的问题.所以我们需要能够帮我们管理这些文件的工具:npm.

装完node,就同时装上了npm,npm就是node模块的管理器.npm管理的模块称为包.包有名称,也有一定的格式.直观的看,npm包就是一个文件夹下符合一定规则的一些文件.

我们可以新建一个文件夹,在cmd里cd到这个文件夹的路径下,执行npm init,点几下回车,就会创建一个npm格式的空包.主要是一个描述信息的package.json文件.而这个文件里最有用的就是他可以帮助我们管理依赖包.就是说,尽管是我们自己写的一个包,但是我们不是什么都自己写,有一些功能别人已经做好了,发布成了npm包,我们就可以作为依赖包添加进来,在我们的package.json文件中声明.主要是写上包的名字和版本.以后npm就可以自动帮我们下载和管理这些包了.省去了我们自己搜索下载的麻烦.

以后我们会经常用到npm的,常用的命令就几条,到时候用到我们再说.用几次就熟悉了.

node环境中的API和浏览器环境中的还是不太一样的.有一些网络,文件之类的操作.不过我们更多时候也是使用更上层的框架来进行开发,对于这些低层的函数,如果有机会要用到,再查文档了解吧.

java里和npm对应的包管理器叫maven.作用差不多,但是maven使用的是xml格式的配置文件.xml的格式像html,使用尖括号括起来的标签,一层一层的嵌套内容的.

java的模块也比js里的概念要多,不仅有更多类型,而且有更多可见性控制.

但是java还有一大堆的名词和理论要学呢.尤其是面向对象的那一大套理论.我们尽可能简单的说吧.


很多地方都使用变量这个概念,但是我们不想使用会变的量,所以我们使用 名称,这个概念.或者统一称为值.

可能叫引用也可以,但是引用已经在计算机里表示了另外一个更为狭窄的概念.

名字 的话,应该是指的古人的名和字,如名关羽,字云长,用在计算机里感觉太不专业,

对象也是一个名称,但是里面可以装其他的名称,所以他是一个容器类型,或者叫引用类型.我觉得统一叫高阶类型,也挺好.

这样我们就有,基本类型,数值,字符串(文本值),boolean值.以及被设置为这些值的名称.

其余的都属于高阶类型,也就是可以存放或指向这些值.当然,多数情况下都会放多个.

而函数也是高阶类型.

比如,我们的

const x = 1

const duixiang = {x : x}

duixiang.x

const hanshu = x => x

hanshu(x)

都可以得到我们放进去的那个值.当然,一个是通过存储得到的,一个是通过运算得到的.这也就意味着,运算和存储之间存在着某种深刻的联系.这种联系不光是在理论上有用,我们在算法理论里也会看到,运算所带来的时间复杂性,和存储带来的空间复杂性,是可以相互转化的.也就是空间换时间,或时间换空间.并且,早期的计算机主要是用于计算,甚至没有永久存储,随着时间,存储变得越来越重要.各种异步,缓存,都是在减少计算,多使用存储.

所以,尽管函数式编程比面向对象出现的更早,但是后来却是面向对象的存储方式流行起来,最近函数式编程开始有复兴迹象,其实里面的多数高阶函数,提供的容器的功能,是使用函数的形式解决存储的问题.但是面向对象轻视函数,使用底层的机器控制流,让简单的运算变得复杂,也是一个大的弊病.运算和存储的选择更多是要根据实际的业务场景.我们只是希望让自己多一些方便实用的工具,在面临具体问题时可以灵活作合适的选择,避免被某种技术的局限带入削足适履的困境.


而赋值和往对象里装对象里装东西的说法,我们统一称为增加(添加)或设置.或者可以简称增设,有则设置,无则增加.这也是现在一种常见的处理方式.

构造函数就是往对象里装名称的函数,其实应该说是对象初始化时会调用的函数.就像vue中的created,也叫生命周期钩子,没有合适的好听的叫法.

而继承,就是一连串的构造函数,挨个往里装名称,从最上面的objet构造函数开始,按照继承链一层一层的执行下来,最后就装好一个包含了所有祖先的对象.


因为在java里凡事都很强调类型,不仅仅是知道这是一个对象,还要知道是什么类型的对象.所以java里引进了类的概念.创建一个对象,就是new 一个类的构造函数. 类还可以继承.就是猫类继承动物类.继承只能是单线条的,不够用了就又整出来一个接口,类可以实现多个接口.为了更好的约束类型的范围,还整出来一个泛型.

你可能感兴趣的:(疾风式全栈教程(9)-语法大班(草稿预览))