刚刚开始的时候感觉不太难,越写越发现之前忽略的可能性很多。
当只有一个变量的时候,把代码写出来不是特别困难。可当有两个变量的时候,情况就复杂了很多。我在刚开始写的时候就在想如何把冗余的代码裁减掉,结果就是大脑宕机。最后老老实实的在纸上,用最笨的方法把所有的可能性都列出来,再去想如何把类似的代码拿出来就变得很容易了。
所以,如果觉得大脑硬件不够用了,那就用最笨的办法先去把事情做了,然后再去优化。
最后写出来的东西
|
|
刚刚开始的时候感觉不太难,越写越发现之前忽略的可能性很多。
当只有一个变量的时候,把代码写出来不是特别困难。可当有两个变量的时候,情况就复杂了很多。我在刚开始写的时候就在想如何把冗余的代码裁减掉,结果就是大脑宕机。最后老老实实的在纸上,用最笨的方法把所有的可能性都列出来,再去想如何把类似的代码拿出来就变得很容易了。
所以,如果觉得大脑硬件不够用了,那就用最笨的办法先去把事情做了,然后再去优化。
最后写出来的东西
|
|
在试图弄清这个问题之前,先要理解栈内存、堆内存和预处理。
|
|
例1的图示
未被占用的堆内存才会被销毁
所以,正如图中椭圆形关键点中说明的那样,堆内存xxxfff111被返回给了全局变量f,而全局变量只有在窗口关闭的时候才会销毁,因此堆内存xxxfff111将一直被占用而不会销毁,定义它的局部作用域A也不会被销毁。
|
|
这段代码的特点是:私有作用域给DOM元素的事件绑定一个方法。
例2的图示:
正如图中椭圆形关键点所说,标签对象的属性里面会自带一个onclick的属性,未被赋值时其值为null。那么,在自执行函数执行的时候,其创建的作用域所占用的堆内存xxxfff111同样也会被全局的堆内存xxxfff000占用(这里要注意,是堆内存占用堆内存),所以堆内存xxxfff111和栈内存A都不会被销毁。
只需要将例1稍作修改。
|
|
例3的图示
由于在函数fn中,xxxfff111是被return的,所以栈内存A的预解释不会处理xxxfff111,它只在fn函数执行的时候才会生成,而函数fn的栈内存A每次被执行之后都会被销毁。
将例3稍作修改,就变成了延时销毁的闭包实例。
|
|
例4的图示:
正如途中椭圆形关键点处所说,fn()()
的意思是在执行完fn()
之后再把返回的值函数执行一遍。因此在子函数执行的时候,堆内存xxxfff111被占用了,相应的栈内存A也将保留。
可堆内存xxxfff111中保存的子函数在执行完成之后还是会被销毁,接着堆内存xxxfff111就作为未被占用的堆内存而被销毁,最终栈内存A也会被销毁。
所以,栈内存在执行完之后会被保留一段时间,这段时间等于其子函数执行的时间。
参考资料:
JavaScript高级程序设计(第三版)。
浏览器是如何运行JavaScript代码的?
看例1:
|
|
用图解释这一行代码是如何执行的。
这是一个简单的图示,现在我们来增加几个概念:栈内存、堆内存和预处理。
栈内存用来存放基本数据类型(Number、String、Boolean、Null和Undefined),在执行完之后销毁。
栈内存与另一个概念息息相关——作用域,即代码的执行环境。上图中左边的栈内存就是全局作用域,而右边的则是局部作用域。全局作用域在浏览器窗口关闭之后才销毁。局部作用域在执行完之后就会销毁。
JavaScript规定,父作用域不能使用子作用域中变量和方程,而反过来是可以的。这个反过来的方向链条则被称为作用域链。
这里需要注意的是,判断子作用域的父作用域是哪一个,要看这个子作用域是在哪里定义的,而不是在哪里执行。
堆内存用来存放引用数据类型(object、array、function、date),在没有被引用之后销毁。
当我们声明和定义了一个引用数据类型之后,这个对象保存在堆内存中,而这个对象的地址则保存在栈内存中以用于引用。
在全局作用域声明和定义的引用数据类型,销毁的方法是手动赋值null。
例2
|
|
例3
|
|
例2的图解
例3的图解
由上两个图解可见,当基本数据类型传递的时候,其实是复制了一个新的数据给另一个变量;而当引用类型传递的时候,复制的仅仅是引用数据类型的地址,两个变量通过地址指向的是同一个堆内存中的数据。
所以在例3中,当我们改变n.a的时候,m.a也同样改变了。
预处理是浏览器在执行代码前要做的任务,它包括变量的声明和函数声明与定义。
预处理是变量提升的原因。
当我们写了var num = 12
这样的一行代码的时候,在执行时其实是分为两步:声明var num
和定义num = 12
。对于变量,预处理只做声明而不做定义。
而相对于函数function fn(){var num 12}
,同样有声明和定义之分,与变量不同的是,预处理时声明和定义全部执行。具体步骤是:声明function fn()
,定义fn() = "{var num = 12}"
。
理解了栈内存、堆内存和预处理之后,重新画出例1的图示:
这里的堆内存xxxfff000被全局作用域的函数fn引用,而全局作用域只有在浏览器窗口关闭的时候才会销毁,所以,只要浏览器窗口没有关闭,则堆内存xxxfff000一直被引用而不会销毁。
参考资料:
JavaScript高级程序设计(第三版);
在一个合适的文件夹下npm初始化
|
|
安装webpack
|
|
创建webpack.config.js文件,也可以鼠标右键创建(下同,省略)。
|
|
建立一个app文件夹
|
|
在app文件夹中建立一个main.js的文件和一个index.html文件
|
|
在main.js中随便写点什么,比如
|
|
在index.html中随便写点什么,其中id要与上面的代码对应
|
|
在webpack.config.js文件中加入如下代码,其中其中publicPath是后面配置webpack.dev.server的时候用的。
|
|
运行以下webpack,先编译下试试,因为只是局部安装,所以运行的时候要这样
|
|
运行完之后就可以在terminal中看到运行的结果,工作目录中也会自动创建了一个build的文件夹,里面有一个bundle.js的文件,这些都是在上面webpack.config.js里面配置的结果。
浏览器打开index.html看看
先进入app文件夹
|
|
打开index.html的三种方法
|
|
安装webpack-dev-server,下面cd的命令就不写了
|
|
把index中的../build/bundle.js
改成/assets/bundle.js
这个与上面设置的publicPath有关。如果没有publicPath,那这个路径就直接写成bundle.js
在命令行输入
|
|
运行了之后命令行会提示端口的号码,这个时候这个命令行在启动服务,在想用命令行打开浏览器就不方便了,所以手动到浏览器输入localhost:8080/index.html
;
另一种iframe模式的操作的区别只在输入的网址:localhost:8080/webpack-dev-server/index.html
以上两种打开网页的方式选用一种即可。
这个时候要注意的是,生成的bundle.js文件在内存中,我们是看不到的。
以后还没多次的使用开启服务的命令,总是这样输入大串的命令实在不合适,所以,到npm初始化时候创建的package.json里面的scripts中加一行代用的命令
|
|
再运行的时候就这样
|
|
运行了服务并打开了网页之后,再改动main.js文件,浏览器就可以自动刷新了。
安装HtmlWebpackPlugin插件
|
|
在webpack.dev.server中添加配置
|
|
运行一下,改动html就可以自动刷新了。
安装style-loader和css-loader
|
|
在main.js中引入style.css,由于main.js上面指定的配置中的入口,所以不再main.js中引入style.css的话,webpack是找不到这个文件的。
|
|
在webpack.dev.server中添加配置,添加在output下面,plugins上面。
|
|
创建一个css,随便写点什么
|
|
在次再运行,修改css就可以自动刷新了。
完整代码在github
参考:
hexo官方给了一些迁移的方法,不过它上面介绍的方法都是把博客文章从hexo系统迁移到其他博客系统的方法。然而我们这里要讨论的是:
当我们更换电脑的时候我们应该怎么办?
所以默认你已经成功利用hexo和github发布博客,如果还没有,可以看一下教程
具体的思路是:在生成的已经推到github上的hexo静态代码出建立一个分支,利用这个分支来管理自己hexo的源文件。
如果能在刚刚配置hexo的时候就想好以后的迁移的问题就太好了,可以省掉很多麻烦,可实际使用中,刚刚配置hexo的时候,好多人都是初学,不会想到以后的问题,我就是这样的。
具体的操作:
克隆gitHub上面生成的静态文件到本地
|
|
把克隆到本地的文件除了git的文件都删掉,找不到git的文件的话就到删了吧。不要用hexo init
初始化。
将之前使用hexo写博客时候的整个目录(所有文件)搬过来。把该忽略的文件忽略了
|
|
创建一个叫hexo的分支
|
|
提交复制过来的文件到暂存区
|
|
提交
|
|
推送分支到github
|
|
到这里基本上就搞定了,以后再推就可以直接git push
了,hexo的操作跟以前一样。
今后无论什么时候想要在其他电脑上面用hexo写博客,就直接把创建的分支克隆下来,npm install
安装依赖之后就可以用了。
克隆分支的操作
|
|
因为上面创建的是一个名字叫hexo的分支,所以这里-b
后面的是hexo,再把后面的gitHub的地址换成你自己的hexo博客的地址就可以了。
这样做完了以后,每次写完博客发布之后不要忘了还要git push
把源文件推到分支上。
只是针对第一次提交
如果发现最后一次的提交出现了错误,需要重新提交,就可以用git commit --amend
。
比如已经提交了README.md,但是发现还有创建一个新文件一块提交
这是就要先把新文件放到暂存区,用git add test.html
再使用命令git commit --amend
,如果出现了一种编辑的模式
直接输入:wq
然后按回车,这里需要注意的是直接输入,直接输入的意思就是不是先按esc或者其他的什么键,直接shift
加L右边的键输入冒号,紧接着加上wq,也就是写入并退出。
新添加到暂存区的文件就被放到同一次提交里面了。
如果是不是添加新的文件,只是觉得在最后一次提交的时候有的文件没有修改完全,那就在修改完了之后,把修改的文件用git add
加到暂存区,其他的步骤跟上面是一模一样的。
如果仅仅是想修改一下最后一次提交的提交信息,那就输入这样的命令
|
|
就可以了,之后没有任何其他的操作
有两种方法,第一种是不用插件的情况,第二种是使用一种hexo的插件。
无论哪种方法都有一个共同的前提:修改_config.yml
配置文件post_asset_folder
项为true
。
创建博客是使用命令创建:
|
|
其中的layout项可以省略,例如:
|
|
使用完命令之后,在source/_post文件夹里面就会出现一个“这是一个新的博客.md”的文件和一个“这是一个新的博客”的文件夹。
下一步就是把需要的图片放到新创建的那个文件夹里面去。
|
|
用此种方法,而不是以前的![]()
方法,前提是你的hexo的版本是hexo3以上,到package.json里面看一下吧。如果不是hexo3以上的版本,那就只能用第二种方法了。
例子
|
|
错误的例子
|
|
这是插件的链接
安装
|
|
之后就可以按照正常的方法使用的,比如:
|
|
和
|
|
都可以实现。
此两种方法除了操作有些区别之外,在图片的显示上也略有不同,第一种的图片信息是会显示出来的,而第二种中括号里面的信息是不会显示的。
先初始化
|
|
加入一个README文件
|
|
第一次提交
|
|
链接远程仓库(已经在远程创建了一个未初始化的仓库)
|
|
第一次push
|
|
这个时候这个已经被git的文件夹里面只有一个README.md的文件,接下来就可以写自己的代码了,在第一次需要提交自己的代码之前,先要规定需要忽略的文件
建立.gitignore文件
|
|
在创建的文件里面加入需要忽略的文件或文件夹例如node_modules/
,具体的过滤选项
|
|
然后在git add --all
和git push
。
在文件夹创建一个package.json
|
|
安装webpack
|
|
新建一个webpack.config.js的文件并配置如下
|
|
__dirname是当前文件夹所在的位置,也就是当前目录的绝对路径,它是一个变量,如果把这个目录放到其他的地方它会自动变化。
在package.json里面加入如下配置。
|
|
package.json中的脚本部分已经默认在命令前添加了node_modules/.bin
路径,所以无论是全局还是局部安装的Webpack,你都不需要写前面那指明详细的路径了。
在webpack.config.js文件中加入source maps,目的是找到代码的错误,方便我们改错
|
|
eval-source-map只是source maps中的一个选项,它更适用于开发阶段,至于source maps有哪些选项,需要自己去查一下了。
用webpack构建本地服务器,目的是在没有后端的情况下也可以模拟后端来帮助前端调试
先安装webpack-dev-server
|
|
然后把配置加到webpack.config.js文件之中
|
|
loader是webpack的加载器,它的功能有点类似于插件(plugin),他与webpack正牌的插件(plugin)是有区别的,loader主要用于加载资源,也可以说是转化资源,把各类语法转化在同一个文件之中。plugin的功能则更加丰富。
安装可以转换json的loader
|
|
修改webpack.config.js文件,把json加载器放到module里面
|
|
可以编译JavaScript的loader,babel
|
|
在webpack.config.js中加入配置
|
|
另外,由于babel的配置一般会比较多,所以webpack支持单独创建文件配置babel,webpack会自动调用,方法是创建一个.babelrc
的文件,用于单独配置babel。
单独配置babel的 情况下,webpack.config.js就要改为
|
|
新文件.babelrc的内容为
|
|
安装处理css的loader
|
|
配置webpack.config.js
|
|
其中!
可以理解成“和”,css文件同时使用这两个加载器处理
css文件也需要放到入口文件里面,现在这个例子的入口文件是main.js
|
|
插件需要使用npm安装
安装之后同样在webpack.config.js里面配置
|
|
npm网速慢
用淘宝npm镜像
临时使用
|
|
长期使用
|
|
|
|
安装的时候就是这样了
|
|