Grunt:JavaScript 世界的构建工具。对于需要反复重复的任务,例如压缩(minification)、编译、单元测试、linting等,自动化工具可以减轻你的劳动,简化你的工作。

运行Grunt构建工具需要依赖以下两个文件:

  • package.json
  • Gruntfile.js。
// 初始化生成package.json
npm init
// 安装grunt至package.json中的devDependencies内
npm install grunt --save-dev
// 安装需要支持的第三方grunt插件
npm install grunt-contrib-uglify grunt-contrib-concat
// 新建Gruntfile.js
touch Gruntfile.js

如果在npm install安装过程中,如果安装过程一直在等待,那就是访问国外网站不稳定的问题,可以使用国内淘宝NPM镜像!

//使用淘宝定制的 cnpm  命令行工具代替默认的 npm:
npm install -g cnpm --registry=https://registry.npm.taobao.org

常用的插件:

  • 实现监控:grunt-contrib-watch
  • 语法检查:grunt-contrib-jshint
  • 压缩:grunt-contrib-uglify
  • 合并:grunt-contrib-concat
  • 编译less:grunt-contrib-less
  • 编译jade:grunt-contrib-jade
  • 同时运行多个任务:grunt-contrib-concurrent

Gruntfile文件的组成部分:

  1. “wrapper”函数:module.exports=function(grunt){}
  2. 项目与任务配置:grunt.initConfig
  3. 加载grunt插件和任务:grunt.loadNpmTasks
  4. 自定义任务

下面我们来配置一个实时编译jade和less的Gruntfile文件,代码如下:

module.exports = function(grunt) {
  // 项目与任务配置
  grunt.initConfig({
    watch: {
      html: {
        files: ['main.jade'],
        tasks: ['jade'],
        options: {
          livereload: true
        }
      },
      css: {
        files: ['less/main.less'],
        tasks: ['less'],
        options: {
          livereload: true
        }
      },
      less:{
          files: ['less/*.less']
      }
    },
    less: {
      development: {
        options: {
          compress: false,
          optimization: 2
        },
        files: {
          'css/main.css': 'less/main.less'
        }
      }
    },
    jade: {
      development: {
        options: {
          pretty: true
        },
        files: {
          'main.html': 'main.jade'
        }
      }
    },    
    concurrent: {
      tasks: ['watch', 'jade', 'less'],
      options: {
        logConcurrentOutput: true
      }
    }
  })
  // 加载grunt插件和任务
  grunt.loadNpmTasks('grunt-contrib-watch')  
  grunt.loadNpmTasks('grunt-contrib-jade')
  grunt.loadNpmTasks('grunt-contrib-less')
  grunt.loadNpmTasks('grunt-concurrent')
  // 注册自定义的grunt任务
  grunt.registerTask('default', ['concurrent'])
}

小结:把机械化重复性的工作,交给机器去做。使用自动化工具可以减轻你的劳动,简化你的工作。

Git:是一个开源的分布式版本控制系统,用以有效、高速的处理从很小到非常大的项目版本管理。分布式相比于集中式的最大区别在于开发者可以提交到本地,每个开发者通过克隆(git clone),在本地机器上拷贝一个完整的Git仓库。

基本的Git工作流程

  1. 在工作目录中修改文件
  2. 暂存文件,将文件的快照放入暂存区域
  3. 提交更新,找到暂存区域的文件,将快照永久性存储到 Git 仓库目录

常用的指令

// 克隆现有的仓库
git clone
// 初始化仓库
git init
// 检查当前文件状态
git status
// 暂存已修改的文件
git add
// 查看已暂存和未暂存的修改
git diff
// 提交更新
git commit -m
// 跳过使用暂存区域
git commit -a -m
// 查看提交历史
git log
// 远程更新
git push

把项目搬进GitHub

首先在github官网新增一个仓库,仓库名如:xiangrenya.com。

git clone https://github.com/leon0407/xiangrenya.com.git
git init
git add .
git commit -m 'first commit'
git push

小结:遇到命令不清楚的时候,可以使用git help,查看相关帮助,一般都能解决问题。

Jade是一个高性能的模板引擎,它深受Haml影响,它是用javascript实现的,并且可以供node使用。

打开命令行工具,安装jade:

npm install  -g jade

如何编译jade文件?首先得指向当前的工作目录

jade  -P -w main.jade

-P:不压缩html,默认是-p,表示压缩html;-w:实时编译jade。

1、由于jade的直观、简约、高效,让UI布局的工作变得不再繁琐。结构逐级向内嵌套,层次分明,增强了结构的可读性,相比于html,维护jade代码变得更加容易。

.page-header
    .page-center
        a
            img.logo(src='css/images/logo.png')
        .page-search
            i.icon-search
            input.search-input(type='text')
            input.btn-search.btn-search-text(type='button',value='搜索')

2、通过extends的方法,可以建立网站模板,甚至嵌套子模板都是可以的,非常方便的管理页面。

// layout.jade 
doctype html
html
    head
        meta(charset='utf-8')
        title my title
        block styles
    body
        header
            //- do something
        block content        
        footer
            //- do something
        block scripts
// about.jade
extends ./layout.jade
block styles
    link(rel="stylesheet", href="css/main.css")
block content
    p 正文...
block scripts
    script(type='text/javascript',src='js/jquery.min.js')
    script.
        alert("hello");

前言:所有关于WordPress使用过程中遇到的问题,都会记录在这篇文章里。

1、WordPress后台登陆缓慢,原因是谷歌Open Sans字体无法访问。

在升级WordPress最新版本WordPress 4.3.1后,出现了网站加载缓慢的现象,打开FireFox的控制台,查看网络,发现原来是无法访问Google字体的请求,然后就把网站源码,搜索到对这部分引用的代码,换成了360网站卫士提供的对Google字体的镜像。

打开wordpress代码中的文件wp-includes/script-loader.php文件

搜索:fonts.googleapis.com找到这行代码:

$open_sans_font_url = "//fonts.googleapis.com/css?family1=Open+Sans:300italic,400italic,600italic,300,400,600&subset=$subsets";

把fonts.googleapis.com替换为fonts.useso.com。这个是360网站卫士常用前端公共库CDN服务提供的对Google字体的镜像。网址:http://libs.useso.com

修改完成保存,刷新网页,实时生效,后台速度恢复正常。

今天公司安排了一天的内训,是关于绩效落地培训,如何打造高效能团队的课程。老师是学心理学专业的,很懂得把控现场的节奏,通过一些小游戏与学员们的互动,提高现场学员的注意力,同时也加深了对知识的理解。

课程的基本内容是围绕4D系统展开,将人的天性分成了4个象限:绿黄蓝橙。

0049QIcRzy6GW4qLWL173&690

通过简短的测试,我的测试结果蓝色,偏向全局和理性。

就我个人而言,我不太喜欢一成不变,面对重复性的工作,我会思考能不能实现自动化或半自动化的工具,来取代现有的这这种不具创造性偏向苦力的工作,以达到高效能开发,节省出时间做更多有意义的事情。如果在时间允许的情况下,我会想办法如何去做优化,或者找到更好的解决方案,做出更有价值的东西。

作为蓝色的人,能够发现好的创意,提供更完美的解决方案,有大局观,对未来会有更长远的考虑。缺点就是不善于人际交往,太过于自我,忽略一些细节。

根据对角线原理,蓝色的人应该多向黄色的人学习他们的长处,提升自己的交际能力,还有多表达一些真诚的感激。

每一个团队里都应该包含这四种颜色的人,各司其职,发挥自己的优势,通力合作,打造最强团队。就像西游记里的师徒四人一样,唐僧具有凝聚力,能够协调徒弟之间的矛盾,属于黄色;猪八戒具有亲和力,能够在一起愉快的合作,属于绿色;孙悟空具有很强的创造力,百分百的投入,属于蓝色;沙和尚具有很强的执行力,从不指责和抱怨,属于橙色。我们尊重他人独立的人格,学会如何与不同颜色性格的人相处,如他所是,而非如你所愿。

每当你感到抱怨的时候,可以尝试用“红转绿”的方法,因为具备亲和力的言语更有利于解决问题以及团队合作,而非刻薄待人。

关于实践应用的策略:感激-包融-展望-指导。在给同事发邮件,给家人朋友发短信,与客户进行洽谈,给上司做工作总结,都可以采取这样的策略,更容易让人信服。

会场墙上张贴的绩效落地矩阵图:

IMG_20151117_125558

继承是OO语言中的一个最为人津津乐道的概念。许多OO语言都支持两种继承方式:接口继承和实现继承。ECMAScript只支持实现继承,而且其实现继承主要是依靠原型链来实现的。

function SuperType(name) {
 this.name = name;
}
SuperType.prototype.sayName = function() {
 alert(this.name);
}
function SubType(name, age) {
 // 继承构造函数的属性和方法
 SuperType.call(this, name);
 this.age = age;
}
SubType.prototype.sayAge = function() {
 alert(this.age);
}
// 继承原型的属性和方法
function obj(o) {
 function F() {}
 F.prototype = o;
 return new F();
}
function inheritPrototype(SubType, SuperType) {
 var prototype = obj(SuperType.prototype);
 prototype.constructor = SubType;
 SubType.prototype = prototype;
}
inheritPrototype(SubType, SuperType);
var sub = new SubType("leon", "25");
sub.sayName();
sub.sayAge();

有人疑问直接用SubType.prototype = SuperType.prototype这样赋值超类的原型可以吗?其实在这里涉及传值和传址的问题。在JavaScript中,赋值语句会用传值和传址两种不同的方式进行赋值,如果是数值型、布尔型、字符型等基本数据类型,在进行赋值时会将数据复制一份,将复制的数据进行赋值,也就是通常所说的传值,如果是数组、hash对象等复杂数据类型,在进行赋值时会直接用内存地址赋值,也就是通常所说的传址。

prototype本质上也是个hash对象,所以直接用它赋值时会进行传址,这样赋值会导致子类原型的改变会影响到超类。我们可以用一种方法实现prototype的传值-new SomeFunction()。

补充:call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是为了改变函数体内部 this 的指向,两者之间的区别在于传递参数的不同。

前言

项目的可维护性放在了第一位,可见其重要性不言而喻。一个项目的可维护性的优劣,会影响到整个项目能否适应新的变化和需求,还有版本的更新迭代,以及维护的时间和人力成本。如果项目开发中,有团队成员code review这个环节,还是至关重要的,因为在一定程度上,这个动作保证了项目的质量。另外,对于大型的网站来说,性能优化也是必不可少的。面对海量数据,javascritpt执行的效率,还是大有文章可做,这对网站的用户体验也是影响深远的。

一、可维护性

可维护性:可理解性、直观性、可适应性、可扩展性、可调试性

1 代码约定

一种让代码变得可维护的简单途径是形成一套JavaScript代码的书写约定。杰出的开放源代码项目有着严格的代码约定要求,这让社区的任何人都可以轻松地理解代码是如何组织的。

1.1 可读性

  • 格式化:建议缩进大小为4个空格
  • 注释:函数和方法、大段代码、复杂的算法、hack

1.2 变量和函数命名

  • 变量名为名词
  • 函数名为动词开始
  • 变量和函数使用合符逻辑的名字,不要担心长度。

1.3 变量类型透明

  • 初始化: var found = false; //布尔型
  • 使用匈牙利标记法来指定变量类型:o代表对象,s代表字符串,i代表整数,f代表浮点数,b代表布尔型
  • 使用类型注释: var found /*:Boolen*/ = false;

2 松散耦合

只要应用的某个部分过于依赖于另一部分,代码就是耦合过紧,难以维护。必须小心这些情况,并尽可能维护弱耦合的代码。

2.1 解耦HTML/JavaScript

HTML和JavaScript应该完全分离,并通过外部文件和使用DOM附加行为来包含JavaScript。JavaScript用于插入数据时,尽量不直接插入标记,可以控制标记的显示和隐藏,而非生成它。另一种方法是进行Ajax请求并获取更多要显示的HTML,这个方法可以让同样的渲染层(PHP、JSP、Ruby)来输出标记。

2.2 解耦CSS/JavaScript

利用JavaScript修改样式时,应该通过动态修改样式类而非特定样式来实现。显示问题的唯一来源应该是CSS,行为问题的唯一来源应该是JavaScript。

2.3 解耦应用逻辑/事件处理程序

应用逻辑和事件处理程序相分离,一个事件处理程序应该从事件对象中获取相关信息,并将这些信息传送到处理应用程序的某个方法中。

好处:可以更容易更改触发特定过程的事件;其次可以在不附加到事件的情况下测试代码,使其更易创建单元测试或者是自动化应用流程。

应用和业务逻辑之间松散耦合的几条原则:

  • 勿将event对象传给其他方法;只传来自event对象中所需的数据
  • 任何在应用层面的动作都应该可以在不执行任何事件处理程序的情况下进行
  • 任何事件处理程序都应该处理事件,然后将处理转交给应用逻辑

3 编程实践

书写可维护的JavaScript并不仅仅是关于如何格式化代码,它还关系到代码做什么的问题。在企业环境中创建的Web应用往往同时由大量人员一同创作。这种情况下的目标是确保每个人所使用的浏览器环境都有一致和不变的规则。

3.1 尊重对象所有权

如果你不负责创建和维护某个对象、它的对象或者它的方法,那么你就不能对它们进行修改。不要为实例或者原型添加属性和方法以及重定义已存在的方法。

3.2 避免全局变量

与尊重对象所有权密切相关的是尽可能避免全局变量和函数。这也关系到创建一个脚本执行的一致的和可维护的环境。最多创建一个全局量,让其他对象和函数存在其中。

3.3 避免与null进行比较

如果看到与null比较的代码,尝试使用以下技术替换:

  • 如果值应为一个引用类型,使用instanceof操作符检查其构造函数
  • 如果值应为一个基本类型,使用typeof检查其类型
  • 如果是希望对象包含某个特定的方法名,则使用typeof操作符确保指定名称的方法存在于对象上

代码中null越少,就越容易确定代码的目的,并消除不必要的错误。

3.4 使用常量

关键在于将数据和使用它的逻辑进行分离。要注意的值的类型如下所示:

  • 重复值
  • 用户界面字符串
  • URLs
  • 任意可能会更改的值

二、性能

因为JavaScript最初是一个解释型语言,执行速度要比编译型语言慢得多。Chrome是第一款内置优化引擎,将JavaScript编译成本地代码的浏览器。此后,主流浏览器纷纷效仿,陆续实现JavaScript的编译执行。

1 注意作用域

随着作用域链中的作用域数量的增加,访问当前作用域以外的变量的时间也在增加。访问全局变量总是要比访问局部变量慢,因为需要遍历作用域链。只要能减少花费在作用域链上的时间,就能增加叫脚本的整体性能。

1.1 避免全局查找

使用全局变量和函数肯定要比局部的开销更大,因为涉及作用域链上的查找。

优化前的代码

function updateUI(){
    var imgs = document.getElementsByTagName("img");
    for(var i=0,len=imgs.length;i<len;i++)
    {
        imgs[i].title = document.title + " image " + i;
    }
    var msg = document.getElementById("msg");
    msg.innerHTML = "Update complete.";
}

优化后的代码

function updateUI(){
    var doc = document;
    var imgs = doc .getElementsByTagName("img");
    
    for(var i=0,len=imgs.length;i<len;i++)
    {
        imgs[i].title = doc .title + " image " + i;
    }
    var msg = doc .getElementById("msg");
    msg.innerHTML = "Update complete.";
}

1.2 避免with语句

在性能非常重要的地方必须避免使用with语句。和函数类似,with语句会创建自己的作用域,肯定会增加其中执行的代码的作用域链的长度。必须使用with语句的情况很少,它主要用于消除额外的字符。在大多数情况下,可以用局部变量完成相同的事情而不用引入新的作用域。

优化前的代码

function updateBody(){
    with(document.body){
        alert(tagName);
        innerHTML = "hello world!";
    }
}

优化后的代码

function updateBody(){
    var body = document.body;
    alert(body.tagName);
    body.innerHTML = "hello world!";
}

2 选择正确方法

性能问题的一部分是和用于解决问题的算法或者方法有关的。老练的开发人员根据经验可以得知哪种方法可能获得更好的性能。

2.1 避免不必要的属性查找

一般来讲,只要能减少算法的复杂度,就要尽可能减少。尽可能多地使用局部变量将属性查找替换为值查找。进也不讲,如果即可以用数字化的数组位置进行访问,也可以使用命名属性。

2.2 优化循环

优化循环是性能优化过程中很重要的一部分,由于他们会反复运行同一段代码,从而自动地增加执行时间。

  • 减值迭代
  • 简化终止条件
  • 简化循环体
  • 使用后测试循环

减值迭代优化

for(var i=values.length; i >= 0 ; i--){
    process(value[i]);
}

后测试循环优化

var i = values.length - 1;
if(i > -1){
    do{
        process(values[i]);
    }while(--i > 0);
}

2.3 展开循环

当循环的次数是确定的,消除循环并使用多次函数调用往往更快。如果循环中的迭代次数不能事先确定,可以使用duff装置技术。

var iterations = Math.floor(values.length / 8);
var leftover = values.length % 8;
if(leftover > 0){
    do{
        process(values[i++]);
    }while(--leftover > 0);
}
do{
    process(values[i++]);
    process(values[i++]);
    process(values[i++]);
    process(values[i++]);
    process(values[i++]);
    process(values[i++]);
    process(values[i++]);
    process(values[i++]);
}while(--iterations > 0);

2.4 避免双重解释

当JavaScript代码想解析JavaScript的时候就会存在双重解释惩罚。当使用eval()函数或者是Function构造函数以及使用setTimeOut()传入一个字符串参数时都会发生这种情况。

2.5 性能的其他注意事项

  • 原生方法较快
  • Switch语句较快
  • 位运算符较快

3 最小化语句数

JavaScript代码中的语句数量也影响所执行的操作的速度。完成多个操作的单个语句要比完成单个操作的多个语句快。所以,就要找出可以组合在一起的语句,以减少脚本的执行时间。

  • 多个变量声明
  • 插入迭代值
  • 使用素组和对象字面量

4 优化DOM交互

在JavaScript各个方面中,DOM毫无疑问是最慢的一部分。DOM操作与交互要消耗大量时间,因为它们往往需要重新渲染整个页面或者某一部分。理解如何优化与DOM的交互可以极大得提高脚本完成的速度。

4.1 最小化现场更新

现场更新:需要立即(现场)对页面对用户的显示进行更新。每一个更改,不管是插入单个字符,还是移除整个片段,都有一个性能惩罚,因为浏览器要重新计算无数尺寸以进行更新。

优化前的代码

var list = document.getElementById("myList"),
                item,
                i;
for(i = 0; i < 10;i ++){
     item = document.createElement("li");
     list = appendChild(item);
     item.append(document.createTextNode("Item " + i));
}

分析:该代码添加每个项目时都有2个现场更新:一个添加<li>元素,另一个给它添加文本节点。总共需要20个现场更新。两种优化方法:第一 种将列表从页面上移除,最后进行更新,最后再将列表插回到同样的位置,这个方法不理想,因为每次页面更新的时候会不必要的闪烁。第二个方法是使用文档片段 来构建DOM结构,接着将其添加到List元素中,这种方法避免了现场更新和页面闪烁问题。

优化后的代码

var list = document.getElementById("myList"),
           fragment.document.createDocumentFragment(),
           item,
           i;
for(i = 0; i < 10;i ++){
     item = document.createElement("li");
     fragment.appendChild(item);
     item.appendChild(document.createTextNode("Item " + i));
}
list.appendChild(fragment);

4.2 使用innerHTML

调用innerHTML(和其他DOM操作一样)关键在于最小化调用它的次数。

页面中创建DOM节点的方法有:使用诸如createElement()和appendChild()之类的DOM方法,以及使用innerHTML。对于小的DOM更改而言,两种方法效率都差不多。然而对于大的DOM更改,使用innerHTML要比使用标准DOM方法创建同样的DOM结构快得多。

因为当把innerHTML设置为某个值时,后台会创建一个HTML解析器,然后使用内部的DOM调用来创建DOM结构,而非基于JavaScript的DOM调用。由于内部方法是编译好的而非解释执行的,所以执行快的多。

var list = document.getElementById("myList"),
           html="",
           i;
for(i = 0; i < 10;i ++){
     html = ">li<" + i + ">li&lt";
}
list.innerHMTL = html;

4.3 使用事件代理

页面上的事件处理程序的数量和页面响应用户交互的速度之间有个负相关,为了减轻这种惩罚,最好使用事件代理。

事件代理用到了事件冒泡,任何可以冒泡的事件都不仅仅可以在事件目标上进行处理,目标的任何祖先节点上也能处理,因此可以将事件处理程序附加到更高层的地方负责多个目标的事件处理,如果在文档级别附加事件处理程序,就可以处理整个页面的事件。

4.4 注意HTMLCollection

访问HTMLCollection,不管它是一个属性还是一个方法,都是在文档上进行一个查询,而且这个查询开销很昂贵,最小化访问HTMLColletcion的次数可以极大地改进脚本性能。

优化HTMLCollection访问最重要的地方在于循环

var images = document.getElementsByTagName("img"),image,i,len;
for(i=0,len=images.length;i < len;i++){
     image = images[i];
    //处理
}

小结

可维护性其实是在说代码规范的重要性,遵守约定的规范,有利于团队的合作,以及项目的后期维护。性能其实是在说一些JavaScript方面的应用技巧,旨在提高脚本的执行效率。

定义

维基百科上的定义:在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。通俗的定义:如果一个函数访问了它的外部函数变量,那么它就是一个闭包。

在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

当你return的是内部function时,就是一个闭包。内部function会访问外部function的变量直到内部function结束。

function foo(x) {
    var tmp = 3;
    return function (y) {
        alert(x + y + (++tmp));
    }
}
var bar = foo(2); // bar 现在是一个闭包
bar(10);

有一个不用return关键字的闭包例子

function closureExample(objID, text, timedelay) { 
    setTimeout(function() { 
        document.getElementById(objID).innerHTML = text; 
    }, timedelay); 
}
closureExample(‘myDiv’, ‘Closure is created’, 500);

闭包的应用

保护函数内的变量安全。以最开始的例子为例,函数a中i只有函数b才能访问,而无法通过其他途径访问到,因此保护了i的安全性。

实际使用的时候,闭包可以创建出非常优雅的设计,允许对funarg上定义的多种计算方式进行定制。

[1, 2, 3].map(function(element) {
    return element * 2;
}); // [2, 4, 6]
[1, 2, 3].forEach(function(element) {
    if(element % 2 != 0) {
     alert(element);
 }
}); // 1, 3

闭包的缺点

由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

结语

闭包是一种设计原则,它通过分析上下文,来简化用户的调用,让用户在不知晓的情况下,达到他的目的。理解JavaScript的闭包是迈向高级JS程序员的必经之路,理解了其解释和运行机制才能写出更为安全和优雅的代码。

jquery的扩展方法extend是我们在写插件的过程中常用的方法,该方法有一些重载原型。

一、Jquery的扩展方法原型

extend(dest,src1,src2,src3...);

它的含义是将src1,src2,src3…合并到dest中,返回值为合并后的dest,由此可以看出该方法合并后,是修改了dest的结构的。如果想要得到合并的结果却又不想修改dest的结构,可以如下使用:

var newSrc=$.extend({},src1,src2,src3...)

这样就可以将src1,src2,src3…进行合并,然后将合并结果返回给newSrc了。如下例:

var result=$.extend({},{name:"Tom",age:21},{name:"Jerry",sex:"Boy"})
 //那么合并后的结果
 result={name:"Jerry",age:21,sex:"Boy"}

也就是说后面的参数如果和前面的参数存在相同的名称,那么后面的会覆盖前面的参数值。

二、省略dest参数

上述的extend方法原型中的dest参数是可以省略的,如果省略了,则该方法就只能有一个src参数,而且是将该src合并到调用extend方法的对象中去,如:

1、将src合并到jquery的全局对象中去:$.extend(src)

$.extend({
  hello:function(){alert('hello');}
});

2、将src合并到jquery的实例对象中去:$.fn.extend(src)

$.fn.extend({
  hello:function(){alert('hello');}
});

3、在jquery全局对象中扩展一个net命名空间

$.extend({net:{}});

4、将hello方法扩展到之前扩展的jquery的net命名空间中去

$.extend($.net,{
  hello:function(){alert('hello');}
})

三、Jquery的extend方法的重载原型

extend(boolean,dest,src1,src2,src3...)

第一个参数boolean代表是否进行深度拷贝,其余参数和前面介绍的一致,什么叫深层拷贝,我们看一个例子:

var result=$.extend( true, {},
{ name: "John", location: {city: "Boston",county:"USA"} },
{ last: "Resig", location: {state: "MA",county:"China"} } );
//合并后的结果
result={name:"John",last:"Resig",
location:{city:"Boston",state:"MA",county:"China"}}

也就是说它会将src中的嵌套子对象也进行合并,而如果第一个参数boolean为false,我们看看合并的结果是什么,如下:

var result=$.extend( false, {}, 
{ name: "John", location:{city: "Boston",county:"USA"} }, 
{ last: "Resig", location: {state: "MA",county:"China"} } );
//合并后的结果
result={name:"John",last:"Resig",location:{state:"MA",county:"China"}}

概述

hexo是一种静态博客框架,无需数据库。可以用MarkDown语言来撰写自己的博客,最后生成静态页面,在github上生成github page,向别人展示自己的博客,其实更像是自己的笔记,只不过的笔记展示的效果比以前的word好了很多。

而wordpress不太一样,它是动态的博客框架,采用的php+mysql的方式,可以管理权限,别人访问可以点赞、留言、评论以及分享。

缺点:安装复杂,无法跟来访者实现互动。

所以说:用hexo实现个人简介、作品展示、技术分享等等页面的展示,以及markdown语言写出来的博文,排版的可读性的非常好,最后放到github page上是再好不过的了。

安装环境

因为以前安装过程中,遇到过一些错误。所以今天又重新安装了一遍,确保整个安装过程是没有问题的。
首先要安装git:http://git-scm.com/download。这个在部署到github上会用到。
然后安装node.js:https://nodejs.org 。因为hexo框架是基于node.js的,并且node.js安装包里包含了npm(node package manager),用来安装hexo。

命令行

在全局的环境下安装hexo-cli
npm install hexo-cli -g
初始化一个名叫blog的文件夹
hexo init blog
进入blog的目录下
cd blog
安装hexo所需的包
npm install
安装配置git的所需的包
npm install hexo-deployer-git –save
新建一个.md的文件
hero new [type] title
在本地启动服务(localhost:4000)
hexo server
生成静态网页
hexo generate
部署到git上(提前需要到_config.yml进行deploy属性的配置)
hexo deploy
如果顺利完成上面的操作的话,就可以在你的github上面看到自己的仓库里已经有文件了。点击设置,就可以看到你的github page了。
官方的文档:http://hexo.io/docs/