不可思议的BUG

莫看江面平如镜,要看水底万丈深——记一次由表象引起的不是BUG的BUG

起因

先上图
image
一位同学碰到了这样一个问题:明明配置的请求地址是ip,为什么变成域名了。

上图,第一行是实际请求报错的接口,第二行才是打印出的真正配置的接口地址,由于项目上会根据项目环境,会切换接口地址,方便开发、测试、生产。我的第一反应就是切换地址的逻辑有问题。仔细跟了他写的代码,确实在接口请求前,地址是开发地址,但请求之后变成了生产地址。

自己折腾了半天,尝试了各种方案:

  • 把地址换成固定的字符串,如aaa,没问题;
  • 将接口定义文件内容简化;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // 简化前
    export default {
    dev: {
    DEV_URL: ''
    },
    test: {
    TEST_URL: ''
    },
    prod: {
    PROD_URL: ''
    }
    }
    // 简化后
    export default {
    dev: '',
    test: '',
    prod: ''
    }
  • 我把生产地址注释掉,发现还调用的是生产地址
阅读更多

前端自动化构建及部署

前言

自动化这个字眼神圣而又高大上,对后端开发的同学来说也许再熟悉不过了,可对于前端开发来说,确实有些遥不可及,接下来分享下,我在前端项目的自动化实践。

实现方式

  • 一套是工作中经常使用的 Docker + Jenkins。Jenkins 是持续集成的关键。
  • 使用 DaoClound

什么是持续集成?

jenkins 的使用成本还是比较高的,因为需要搭建 Jenkins 的基本环境,但使用率想到高。我主要介绍的是第二套方案,成本低,但能实现自动化的功能。

阅读更多

前端进阶系列—HTML5新特性

HTML5 是对 HTML 标准的第五次修订。其主要的目标是将互联网语义化,以便更好地被人类和机器阅读,并同时提供更好地支持各种媒体的嵌入。HTML5 的语法是向后兼容的。现在国内普遍说的 H5 是包括了 CSS3,JavaScript 的说法(严格意义上说,这么叫并不合适,但是已经这么叫开了,就将错就错了)。

语义特性

HTML5 赋予网页更好的意义和结构

  • 文件类型声明(<!DOCTYPE>)仅有一型:<!DOCTYPE HTML>。
  • 新的解析顺序:不再基于 SGML。
  • 新的元素:section, video, progress, nav, meter, time, aside, canvas, command, datalist, details, embed, figcaption, figure, footer, header, hgroup, keygen, mark, output, rp, rt, ruby, source, summary, wbr。
  • input 元素的新类型:date, email, url 等等。
  • 新的属性:ping(用于 a 与 area), charset(用于 meta), async(用于 script)。
  • 全域属性:id, tabindex, repeat。
  • 新的全域属性:contenteditable, contextmenu, draggable, dropzone, hidden, spellcheck。
  • 移除元素:acronym, applet, basefont, big, center, dir, font, frame, frameset, isindex, noframes, strike, tt。

本地存储特性

HTML5 离线存储包含:应用程序缓存(Application Cache)本地存储索引数据库文件接口

阅读更多

前端进阶系列—常见布局及居中

水平居中布局

margin+定宽

1
2
3
4
5
6
7
8
9
10
<div class="parent">
<div class="child">Demo</div>
</div>

<style>
.child {
width: 100px;
margin: 0 auto;
}
</style>
  • 想必是个前端都见过,这定宽的水平居中,我们还可以用下面这种来实现不定宽

table+margin

1
2
3
4
5
6
7
8
9
10
<div class="parent">
<div class="child">Demo</div>
</div>

<style>
.child {
display: table;
margin: 0 auto;
}
</style>
阅读更多

前端进阶系列—SEO 和语义化

基本概念

SEO:(Search Engine Optimization)意为搜索引擎优化。搜索引擎优化是一种利用搜索引擎的搜索规则来提高目的网站的自然排名的方式。说白了就是对品牌的自我宣传,从而获取收益。

HTML 语义化:根据内容的结构的语义化,选择合适的标签(代码语义化)便于开发者阅读和写出更优雅的代码的同时利于 SEO 优化。

使用 SEO 和语义化的目的

前面也做了基本的阐述:

  • SEO 就是为了对品牌的自我宣传,从而获得收益;
  • 语义化的目的:
    • 在没有 css 的情况下,页面也能呈现出很好的内容结构,代码结构;
    • 提升用户体验:例如 title、alt 用于解释名词和解释图片信息;
    • 有利于 SEO 优化:和搜索引擎建立良好的沟通,有助于爬虫抓取更多的有效信息,爬虫依赖于标签来确定上下文和各个关键字的权重;
    • 方便其他设备解析如屏幕阅读器、盲人阅读器、移动设备;
    • 语义化更据有可读性,便于团队开发和维护。
阅读更多

前端进阶系列

HTML/CSS 篇

  1. SEO 和语义化
  2. 常见布局及居中
  3. HTML5 新特性
  4. CSS3 新特性
  5. flex 布局
  6. 盒模型

JS 篇

  1. 什么是执行上下文
  2. JS 执行机制
  3. 从原型到原型链
  4. 词法作用域和动态作用域
  5. 变量对象
  6. 作用域链
  7. 从 ECMAScript 规范解读 this
  8. 闭包
  9. 参数按值传递
  10. call 和 apply 的模拟实现
  11. bind 的模拟实现
  12. new 的模拟实现
  13. 类数组对象与 arguments
  14. 创建对象的多种方式以及优缺点
  15. 继承的多种方式及优缺点

算法篇

  1. 各种排序,重点是块排
  2. 动态规划,参见背包问题
  3. 二叉树
阅读更多

深入理解JavaScript系列—从原型到原型链

本文主要摘抄自冴羽大佬的blog。

1
2
原文作者:冴羽
原文地址:https://github.com/mqyqingfeng/Blog/issues/2


学过Java的同学应该知道,有类继承的概念,对于JavaScript这种动态语言来说,不通过类继承的功能,即便在ES6里面引入了class关键字,也只是语法糖,基本值还是基于原型prototype实现的。

先介绍几个概念:

什么是对象

若干属性的集合

阅读更多

深入理解JavaScript系列—constructor、prototype、_proto_ 详解

本文为了解决一下问题:

  • _proto_(实际原型)和prototype(原型属性)不一样!!!
  • constructor属性(原型对象中包含这个属性,实例当中也同样会继承这个属性)
  • prototype属性(constructor.prototype原型对象)
  • _proto_属性(实例指向原型对象的指针)

首先弄清楚几个概念:

什么是对象

若干属性的集合

什么是原型

阅读更多

认识原型对象和原型链

在 javascript 中,万物皆对象,但对象也有区别,大致可以分为两类,即:普通对象 Object函数对象 Function
一般而言,通过 new Function 参省的对象时函数对象,其他对象都是普通对象。
举例说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function f1(){
//todo
};

var f2=function(){
//todo
};

var f3=new Function('x','console.log(x)');
var o1={};
var o2=new Object();
var o3=new f1();
console.log(
typeof f1,//function
typeof f2,//function
typeof f3,//function
typeof o1,//object
typeof o2,//object
typeof o3 //object
);
>> function function function object object object

f1 属于函数的声明,最常见的函数定义,f2 实际上是匿名函数,属于函数表达式,f3 不常见,但也是一种函数对象。

Function 是 JS 的自带的对象,f1,f2 在创建的时候,JS 会自动通过 new Function()的方式来构建这些对象,因此这三个对象都是通过 new Function()创建的。

在 JavaScript 中创建对象的方式有两种:对象字面量和使用 new 表达式,o1 和 o2 的创建恰好对应了这两种方式,重点讲一下 03,如果用 java 和 c#的思路来理解的话,o3 是 f1 的实例对象,03 和 f1 是同类型,至少以前我是这么认为的,其实不然……

怎么理解呢?很简单,看 o3 是不是通过 new Fuction()产生的,显然不是,既然不是函数对象,那就是普通对象。

阅读更多

语音控制灯

这是之前做的一个物联网的demo,给大家做个演示。