自2018/7/6号起,基于gitpage搭建个人blog迁置个人服务器

由于以下原因,很不舍就要放弃刚刚搭建没多久的这个静态页面(滑稽)。

主要有以下原因:

github相关资源的加载实在是太太太太太太慢了!

做了以下操作,做cdn静态资源加速,但是!公共的cdn服务器都没有缓存hexo和aria用的工具包。
那么我自己搭一个咯。。。。。oss空间了解了后,
得绑定域名吧?
还得备案吧?
备案得要服务器吧?
然后就脑子一热就往阿里baba那里冲了钱。。。
再然后突然醒悟!
既然如此,我TMD不直接用把blog放在服务器上呢?
还加速个球喔!

以上就是本咸鱼的心路历程(鞠躬)~

该文章阅读需要8分钟,更多文章请点击本人博客halu886


当函数可以记住并访问所在的词法作用域,即使是在当前作用域外执行,这时就产生了闭包. —–<<你不知道的JavaScript(上卷)>>

闭包是基于词法作用域书写代码时所自然产生的结果.

本质

function foo(){
    var a = 'test';
    function bar(){
        console.log(a);
    }
    bar()//test;
}

由词法作用域概念我们可以将这段代码理解为foo()中存在一个作用域,bar()中存在一个词法作用域

foo作用域包含bar作用域,bar作用域被foo作用域包含.

且根据词法作用域可知对于变量的检索可以由当前作用域向上层作用域进行遍历直至顶层作用域.

function foo(){
    var a = 'test';
    function bar(){
        console.log(a);
    }
    return bar;
}

var baz = foo();
baz();//test

bar函数所含有的作用域引用了foo函数的作用域,且当执行foo()时,bar函数作为一个返回值返回,baz变量引用着词法作用域,当bar在全局作用域下执行时,bar指向的作用域既能访问foo指向的作用域,还能指向全局作用域.

按照JavaScript引擎执行逻辑作用域在执行完后且没有被引用后就会被垃圾回收机制回收,但是当foo()方法执行完,baz依旧引用bar方法的作用域,那么foo()执行完后依旧存在引用,foo作用域将不会被回收.

var fn;
function foo(){
    var a = 2;
    function bar(){
        console.log(a);
    }
    fn = bar;
}

function baz(){
    fn();
}

foo()

baz()//2

只要作用域内部的子作用域被作用域外引用并执行就构成了闭包

“回调===闭包”

在jquery,定时器,触发事件等等中大量的第三方API存在回调函数,比方说:

function fn(message){
    setTimeout(function time(){ //回调===闭包
        console.log(message);
    },1000)
}

fu('test')//test

在大部分(几乎所有)的第三方API中的回调都属于闭包(在作用外执行方法)

循环和闭包

在关于大部分闭包的思考中,都会提到循环和传入定时器中闭包所产生的问题

for(var i=0;i<5;++i){
    setTimeout(function(){
        console.log(i);
    },1000);
}
//5
//5
//5
//5
//5

首先我们得先理解定时器中回调函数执行的时刻是在for循环结束后,那么向事件循环中设置的五个匿名函数是for循环遍历完后才执行的。

根据之前我们梳理的概念,匿名函数所指向的作用域能够访问上一级的作用域,此时上一级的作用域的i变量指向常量5.

那么问题来了?
如何达到我们想要的效果,每次输出植入定时器是循环索引?

方法1:

//作用域a
for(var i=0;i<5;++i){
    (function(){
        //作用域b
        var j = i;
        setTimeout(function(){
            //作用域c
            console.log(j);
        },1000);
    })();
}
//0
//1
//2
//3
//4

这里我们用的思路是嵌套一层作用域进行保存索引i。遍历五次后,多生成五个作用域b,里面分别保存各次遍历时的索引i(定义一个新变量j指向索引常量).

当回调执行时先在作用域c寻找变量j,没有得到时,再去上一层作用域b,找到了后停止向上遍历,输出j。

方法2:

//作用域a
for(let i = 0;i<5;++i){//es6语法let关键字
    //作用域b
    setTimeout(function(){
        //作用域c
        console.log(j);
    },1000);
}
//0
//1
//2
//3
//4

这里运用了es6中的let关键字,生成块级作用域本质上和方法一同理,这里不再赘述.

以上就是对闭包的总结,大部分js中模式都风骚的运用了闭包的特性。更多知识建议阅读《你不知道的JavaScript》

该文章阅读需要12分钟,更多文章请点击本人博客halu886


工作

输出

季度输出

表格中大致汇总了实习期间一年下来的在公司所埋得坑:-)

工作期间虽然走过很多弯路,被领导diss了不少次,但所幸自己成长的速度还算更上进度而且也稍微达到了预期的一部分:-)

在实习期间主要是在大eAudit项目组中担任前后端的开发.也支援过common模块和PQM模块,同时还本着”机会是留给敢背锅的人“的原则担起过官网项目和调漆项目.

总结实现了10个以上需求,整改了85个以上优化项,修复了143个以上的bug.而且随着工作时长的增加,输出的质量和效率都有了飞跃的提升:-)

但是在以上工作经验中接触的面越来越广,所需要的知识也越来越多和迫切.深感自己在很多方面的欠缺.这也是不断的在激励我不断学习不断成长

落后就要挨打

反思与总结

反思

  • 成长不够多元
  • 空闲时间利用不够合理

Q2的时候除了工作以外大部分时间都花在了六级复习和毕设的编写上.结果最后回学校的时候,由于论文规范完全不达标,相关设计和需求分析一点也不专业导致被老师骂惨了.

这时候我才发现实习一年后其实我只学会如何代码打交道,接到一个明确的目的通过编程的方式实现.在软件工程其他方面所涉及的工作所知道还停留在学校里的水平.

一直都坚持上班前和下班后花时间积累和成长,但也确实走了不少弯路,所需要使用的各种技术的书都看了很多,Demo也练习了不少.但是产出没有想象的大.

总结

  • 职业规划越来清晰
  • 在技术增强的道理上逐渐摸索出适合自己方法

虽然踩了很多坑,可是慢慢的对于自己的职业规划越来越清晰明了.

  1. 作为一个应届生码农应该如何成长?
  2. 工作和个人能力应该如何实现互相促进的效果?
  3. 短期内的目标和规划是什么?

这些问题都慢慢都开始有了自己的答案

且在工作和学习的过程,本学渣也逐渐懂得了如何用有效率和投入的方式来学习,而且懂得了如何平衡工作和学习还有生活三者.

未来展望

  • 承担更多职责锻炼自己
    方案:
    • 任务分工时勇于承担和尝试
    • 敢于接触陌生的领域
  • 保持求知欲
    方案:
    • 坚持业余时间学习
    • 定制每周写技术博客计划

在工作中懂得了一个比较深刻的道理

黑猫白猫能抓耗子就是好猫

无论知道多少理论和知识,不能及时合理的实现功能就是白搭.
只有在实践中才能检验个人能力.
所以希望在以后的工作生涯中全身心的投入到具体工作中,别出现本末倒置的情况.

只有不断的成长才能不被淘汰,自制是通往幸福的唯一通道,共勉~

该文章阅读需要8分钟,更多文章请点击本人博客halu886


1.原生函数基本概念

1.1原生函数是什么

JavaScript为基本数据类型提供了封装对象,被称为原生函数(native function),同时也叫内建函数(built-in function)

常用的原生函数有:

  • Number()
  • String()
  • Boolean()
  • Array()
  • Object()
  • Function()
  • RegExp()
  • Date()
  • Error()
  • Symbol()//ES6新加入!

1.2作用是什么

为基本数据类型提供该子类所特有的方法和属性

比如说:String#trim(),Array#Array#concat()  

1.3补充

原生函数同时也能当做构造函数使用

let a = new String("abc");

a instanceof String;//true

通过构造函数创建了一个封装了基本数据类型的封装对象

2.[[class]]

let a = new String("abc");
typeof a;//"object" 

所有typeof返回的”object”的对象都有一个[[class]]属性

Object.prototype.toString.call(new String("abc"));//"[object String]"
Object.prototype.toString.call(new Number(1346));//"[object Number]"
Object.prototype.toString.call(null);//"[object Null]"
Object.prototype.toString.call(undefined);//"[object Undefined]"
//返回一个字符串类型的基本类型数据,格式为[object Xxxxx]

虽然不存在Null()和Undefined()原生函数,但是[[Class]]内部属性仍为这个

3.封装对象包装

当基本数据类型需要调用原生对象的方法和属性时,JavaScript会自动进行对象封装(object wrapper)

疑问:既然如此为什么不直接在变量声明时,直接定义为封装对象?

思考:

  1. JavaScript对基本数据类型的常见情况做了性能优化,直接使用封装对象来进行”提前优化“反而会降低执行效率
  2. 篡改数据类型,提升风险

    let a = false;
    !!false;//false
    let b = new Boolean(false);
    !!b;//true  
    
    //显性类型转换!!Object===>true  
    

4.拆封

当需要用到封装对象的基本类型值时,就需要用到valueOf()

var a = new String("sadflk");
var b = new Number(123);
var c = new Boolean(true);

a.valueOf()//"sadflf"
b.valueOf()//123
c.valueOf()//true

在需要用到基本类型值的时候会发生隐形拆封

技术说明

mongodb

一张用户表user,一张数据表idea(意见)。

//user表数据字段
userName: String,//用户名称
password: String //登入密码
idea表数据字段
productType: String, //产品类型
headLine: String,  //标题
phoneNum: String,  //联系方式
status: String,    //状态 已回复/未回复/已完成
reply: String,      //回复
publishDate: Date,  //发布日期
replyDate: Date,    //回复日期
fileName: Array,    //图片名称
filePath: Array,    //文件路径
user_id: String    //引用用户ID

mongodb 对象的操作用了mongoose模块封装了CURD操作

nodejs

基于node.js中express模块搭建http服务
监听本地localhost:3000端口访问

使用express4.x中的router中间件将请求分离成/user/以及/idea/.
将app.js中的请求转移到了./router/index.js

module.exports=function(app) {
        /**主界面 */
            app.get('/',index);//主页面请求
            app.use('/user',user);//用户模块
            app.use('/idea',idea);//意见模块
        }

在app.js只需要调用./router/index模块,就可以减少主界面请求的代码量
var index = require(./router/index);
index(app);

分别封装user和idea业务逻辑在模块中实例化express.router对象 ./router/idea.js ./router/idea.js

var router=require("express").Router();

在对外开放router对象
module.exports=router;

mongoose封装对于对象的CURD操作
首先我先封装db数据库连接对象的创建

var mongoose=require(‘mongoose’);
var url=’mongodb://localhost:27017/demo’;
mongoose.connect(url);//连接
module.exports=mongoose;

通过mongoose中封装好的scheme对象将我们数据字段封装好,通过model对象实例化,再导出包含一系列查询以及增加删除等等的操作的对象,简直就是开箱即用。

var mongoose=require('./mongoose');
var ideaSchema=new mongoose.Schema({   //Schema对象封装
        /* idea数据字段*/
});

//idea对应的mongodb中的collection,传入Schema对象,将返回model对象对外开放

module.exports=mongoose.model('idea',ideaSchema)

webix

在ejs渲染引擎下使用webix控件

这一部份代码讲道理写得我有点蒙 = =
ejs通过渲染表达式动态传递值或者对html页面进行一些操作
然而webix就是通过封装控件,在js中传递json对象进行构造html中的节点
公司当时说要webix,我又脑子抽到了不愿意舍弃ejs(简直有毒,在这个demo里ejs的唯一作用就是将我conter内容整合到layout里面)。
为了能让ejs稍微有点作用,我在layout界面中写了构建页面中比较不容易改动的top和footer部分。
对你没想错,写在html内置的js中的,然后从不同的界面中传进去各自内置的js(因为webix主要的优势就是让你不用写html代码),所以ejs最后整合到的一起的页面就是两个不同js脚本。感觉ejs在我这里基本没有作用
前端主要就是通过不同的控件构造一个个不同的页面加上一些按钮的触发事件发送webix中封装的ajax提交请求
代码我就不贴了,源码链接我也放出来了,有兴趣就自己去看看吧

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment