GithubHelp home page GithubHelp logo

front-end-knowledge's Introduction

Hi there 👋

Hello

front-end-knowledge's People

Contributors

clarencec avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

front-end-knowledge's Issues

URL URI URN区别

URI

统一资源标识符(Uniform Resource Identifier,或URI)是一个用于标识某一互联网资源名称的字符串.用来唯一的标识一个资源
Web上可用的每种资源如HTML文档、图像、视频片段、程序等都是一个来URI来定位的
URI一般由三部组成
①访问资源的命名机制
②存放资源的主机名
③资源自身的名称,由路径表示,着重强调于资源。

URL

是统一资源定位符,则是具体的资源标识的方式.
URL是Internet上用来描述信息资源的字符串,主要用在各种WWW客户程序和服务器程序上,特别是著名的Mosaic。采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。URL一般由三部组成
①协议(或称为服务方式)
②存有该资源的主机IP地址(有时也包括端口号)
③主机资源的具体地址。如目录和文件名等

作者:郭无心
链接:https://www.zhihu.com/question/21950864/answer/66779836
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

URN

URL的一种更新形式,统一资源名称(URN, Uniform Resource Name)不依赖于位置,并且有可能减少失效连接的个数。但是其流行还需假以时日,因为它需要更精密软件的支持。

例如:
URL: http://www.acme.com/
URI: http://www.acme.com/support/suppliers.htm

URL是URI命名机制的一个子集
参考地址

前端深入学习的文章 I

JavaScript

Html5

CSS3

H5移动端

Git

Other

NPM

Webpack

MongoDB

Vue

框架

Node

Jquery

模块化

性能

方法论

工具

浏览器原理

职业规划

px 、em 和 rem的区别

CSS 的单位 px、em、rem 的区别和使用场景

PX

px 像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。有一个问题点有时候每个设备的显示分辨率不一样,固定的px会固态化不能适应多设备场景。如果为字体font-size设定 px。字体也不能动态变化。

EM

em是相对长度单位。相对于当前对象font-size 的单位,会继承父级元素的字体大小,即倍数。浏览器的默认字体高都是 16px,未经调整的浏览器显示 1em = 16px。但是有一个问题,如果设置 1.2em 则变成 19.2px,问题是 px 表示大小时数值会忽略掉小数位的(你想像不出来半个像素吧)。而且 1em = 16px 的关系不好转换,因此,常常人为地使 1em = 10px。这里要借助字体的 % 来作为桥梁。

因为默认时字体 16px = 100%,则有 10px = 62.5%。所以首先在 body 中全局声明 font-size=62.5%=10px,也就是定义了网页 body 默认字体大小为 10px,由于 em 有继承父级元素字体大小的特性,如果某元素的父级没有设定字体大小,那么它就继续了 body 默认字体大小 1em = 10px。

但是由于 em 是相对于其父级字体的倍数的,当出现有多重嵌套内容时,使用 em 分别给它们设置字体的大小往往要重新计算。比如说你在父级中声明了字体大小为 1.2em,那么在声明子元素的字体大小时设置 1em 才能和父级元素内容字体大小一致,而不是1.2em(避免 1.2*1.2=1.44em), 因为此 em 非彼 em。再举个例子:

<span>Outer <span>inner</span> outer</span>

body { font-size: 62.5%; }
span { font-size: 1.6em; }

结果:外层 <span> 为 body 字体 10px 的 1.6倍 = 16px,内层 <span> 为外层内容字体 16px 的 1.6倍 = 25px(或26px,不同浏览器取舍小数不同)。

明显地,内部 <span> 内的文字受到了父级 <span> 的影响。基于这点,在实际使用中给我们的计算带来了很大的不便。

em 注意规则:

  1. em的值是相对font-size 的值来计算的。
  2. 如果当前组件没有 font-size的值,会继承父级的字体大小。
  3. 一般会在body选择器中声明Font-size=62.5%;(用已将 1em = 10px方便计算)
  4. 计算时将你的原来的px数值除以10,然后换上em作为单位,就可以快速得出像素结果;
  5. 重新计算那些被放大的字体的em数值。避免字体大小的重复声明。和避免字体大小出现小数点像素的情况。也就是避免1.2 * 1.2= 1.44的现象。比如说你在#content中声明了字体大小为1.2em,那么在声明p的字体大小时就只能是1em,而不是1.2em, 因为此em非彼em,它因继承#content的字体高而变为了1em=12px。

REM (CSS3)

rem 也是相对长度单。 rem 是相对于根元素 (<html>) 的单位,rem的出现再也不用担心还要根据父级元素的 font-size 计算 em 值了。因为它始终是基于根元素(<html>)的。
比如默认的 html font-size=16px,那么想设置 12px 的文字就是:12÷16=0.75(rem)
仍然是上面的例子,CSS改为:

html { font-size: 62.5%; }
span { font-size: 16px; font-size: 1.6rem; } //定义 rem 的同时也定义 px,进行降级

结果:内外 的内容均为 16px。

需要注意的是,为了兼容不支持 rem 的浏览器,我们需要在各个使用了 rem 地方前面写上对应的 px 值,这样不支持的浏览器可以优雅降级。

em 和 rem 在什么场景下使用最合理呢?

参考一下这两篇外文

  1. 综合指南: 何时使用 Em 与 Rem
  2. REM vs EM

外文引用

  1. px、em、rem区别介绍
  2. css: 区别 px、em、rem
  3. 综合指南: 何时使用 Em 与 Rem
  4. REM vs EM

Git Pull 更新到本地 和 本地文件有冲突的时候的3种处理方法

Commit your changes or stash them before you can merge

当你本地的版本与远程仓库的版本不一样的时候,而你又想拉下来可以尝试这几种方法

1. Open New Branch

git checkout HEAD^ file/to/overwrite
git pull

2. Overwrite All Local file

git reset --hard
git pull

3.commit your changes befor you do the merge

git stash
git merge origin/master
git stash pop

4. pull remote and loacl

'git fetch -p'

Git 安装配置与知识点

image

Git 是一个版本管理工具等同于SVG,用来管理代码.
1.Git安装
官网下载的安装包 地址

2.Git 安装与教学
廖雪峰 地址

3.Git 常用方法
常用方法,阮一峰地址

遇到的问题:

  • 添加文件 fatal: pathspec 'readme.txt' did not match any files 方法地址

如何写出漂亮的React组件

SFC:Stateless Functional Component

我觉得我们在开发中经常忽略掉的一个模式就是所谓的Stateless Functional Component,不过这是我个人最爱的React组件优化模式,没有之一。我喜爱这种模式不仅仅因为它们能够减少大量的模板代码,而且因为它们能够有效地提高组件的性能表现。总而言之,SFC能够让你的应用跑的更快,长的更帅。

如果我们用正统的React组件的写法,可以得出如下代码:

export default class RelatedSearch extends React.Component {
  constructor(props) {
    super(props);
    this._handleClick = this._handleClick.bind(this);
  }
  _handleClick(suggestedUrl, event) {
    event.preventDefault();
    this.props.onClick(suggestedUrl);
  }
  render() {
    return (
      <section className="related-search-container">
        <h1 className="related-search-title">Related Searches:</h1>
        <Layout x-small={2} small={3} medium={4} padded={true}>
          {this.props.relatedQueries.map((query, index) =>
            <Link
              className="related-search-link"
              onClick={(event) =>
                this._handleClick(query.searchQuery, event)}
              key={index}>
              {query.searchText}
            </Link>
          )}
        </Layout>
      </section>
    );
  }
}

而使用SFC模式的话,大概可以省下29%的代码:

const _handleClick(suggestedUrl, onClick, event) => {
  event.preventDefault();
  onClick(suggestedUrl);
};
const RelatedSearch = ({ relatedQueries, onClick }) =>
  <section className="related-search-container">
    <h1 className="related-search-title">Related Searches:</h1>
    <Layout x-small={2} small={3} medium={4} padded={true}>
      {relatedQueries.map((query, index) =>
        <Link
          className="related-search-link"
          onClick={(event) =>
            _handleClick(query.searchQuery, onClick, event)}
          key={index}>
          {query.searchText}
        </Link>
      )}
    </Layout>
  </section>
export default RelatedSearch;

代码量的减少主要来源两个方面:

没有构造函数(5行)
以Arrow Function的方式替代Render语句(4行)
实际上,SFC最迷人的地方不仅仅是其代码量的减少,还有就是对于可读性的提高。SFC模式本身就是所谓纯组件的一种最佳实践范式,而移除了构造函数并且将_handleClick()这个点击事件回调函数提取出组件外,可以使JSX代码变得更加纯粹。另一个不错的地方就是SFC以Arrow Function的方式来定义了输入的Props变量,即以Object Destructring语法来声明组件所依赖的Props:

const RelatedSearch = ({ relatedQueries, onClick }) =>

这样不仅能够使组件的Props更加清晰明确,还能够避免冗余的this.props表达式,从而使代码的可读性更好。
转载至王下邀月熊_Chevalier

Flux 入门

概念

Flux 是用来构建用户端 Web 应用的架构,它包含三个核心概念:Views, Stores 和 Dispatcher,还有一些次级概念:Actions, Action Types, Action Creators 和 Web Utils。

核心概念

  • Views 即 React 组件。它们负责渲染界面,捕获用户事件,从 Stores 获取数据。
  • Stores 用于管理数据。 一个 Store 管理一个区域的数据,当数据变化时它负责通知 Views。
  • Dispatcher 接收新数据然后传递给 Stores,Stores 更新数据并通知 Views。

次级概念

  • Actions 是传递给 Dispatcher 的对象,包含新数据和 Action Type。
  • Action Types 指定了可以创建哪些 Actions,Stores 只会更新特定 Action Type 的 Actions 触发的数据。
  • Action Creators 是 Actions 的创建者,并将其传递给 Dispatcher 或 Web Utils。
  • Web Utils 是用于与外部 API's 通信的对象。例如 Actions Creator 可能需要从服务器请求数据。

结构和数据流

flux

一个单向数据流是Flux模式的核心,上面示图应该是Flux程序员心中主要的模型图。dispatcher 存储和视图是有着不同输入输出的独立节点,Action动作是一个简单对象,只是包含新的数据和一个标识符类型的属性。

 视图也许引起新的动作Action,这个动作作为用户交互的响应将在整个系统传播.

flux

所有通过dispatcher的数据流将作为一个集中式Hub,动作Action在一个action creator方法中被提供给dispatcher,这个动作通常来自于视图中用户的交互,dispatcher然后调用存储已经注册其中的回调函数,分发Action动作到所有的存储,在它们注册的回调函数中,存储会响应每个和它保存的状态有关的每个动作Action,存储然后发射一个 change改变的事件去提醒controller-view控制器-视图,更新到刚刚改变的新数据。controller-view监听这些事件,然后在一个事件处理器中从存储中获取数据,controller-view调用它们自己的"setState()"方法,这会触发视图的重新渲染,包括DOM组件树中所有更新。

flux

学习事例 starter kit 官方示例

文章参考 segmentfault

React 引入 JSX 时候 报错 Unexpected token '<' Error

React 使用 JSX 语法的时候 需要转义

如果不转义就会报错 "Unexpected token '<' Error"
转义的时候需要
导入 Babel 旧版本 包
\browser.js
或者导入
Babel 新版本 包
babel.min.js

同时要在脚本中添加 type 有两种方法
<script type="text/babel">... </script>
<script type="text/jsx">... </script>

npm install --save 与 npm install--save -dev 区别

--save-dev 是你开发时候依赖的东西,--save 是你发布之后还依赖的东西。

比如,你写 ES6 代码,如果你想编译成 ES5 发布那么 babel 就是devDependencies。
如果你用了 jQuery,由于发布之后还是依赖jQuery,所以是dependencies。

但是在 npm 里面除了二进制的依赖,似乎也不用区分是不是dev。
因为使用npm就是自己编译的意思,而不使用npm直接拿编译后的版本的,这些依赖项也看不到。

引用segmentfault

JavaScript for of 与 for in 的区别

简单说,for in是遍历键名,for of是遍历键值。例如:
`let arr = ["a","b"];
for (a in arr) {
console.log(a);//1,2
}

for (a of arr) {
console.log(a);//a,b
}`
由于for of的这个特性,他还可以实现对iterator对象的遍历,而for in就是简单的遍历了。

ES6 ... 三点运算符

  1. 第一个叫做 展开运算符(spread operator),作用是和字面意思一样,就是把东西展开。可以用在array和object上都行。
    比如:
let a = [1,2,3];  
let b = [0, ...a, 4]; // [0,1,2,3,4]   
let obj = { a: 1, b: 2 };  
let obj2 = { ...obj, c: 3 }; // { a:1, b:2, c:3 }  
let obj3 = { ...obj, a: 3 }; // { a:3, b:2 }  
  1. 第二个,第三个叫做 剩余操作符(rest operator),是解构的一种,意思就是把剩余的东西放到一个array里面赋值给它。一般只针对array的解构,其他的没见过。。。
    比如:
let a = [1,2,3];  
let [b, ...c] = a;  
b; // 1  
c; // [2,3]  
  
// 也可以  
let a = [1,2,3];  
let [b, ...[c,d,e]] = a;  
b; // 1  
c; // 2  
d; // 3  
e; // undefined  
  
// 也可以  
function test(a, ...rest){  
  console.log(a); // 1  
  console.log(rest); // [2,3]  
}  
  
test(1,2,3)  

还有类似的

let array = [1, 2, 3, 4, 5];  
const { x, y, ...z } = array;  
// 其中z=[3, 4, 5],注意如果由于array的length不足以完成析构,则会导致z为[]  
对象:  
let obj = { name: 'zhangsan', age: 30, city: 'shenzhen' };  
const {name, ...others} = obj;  
console.log(name); // 'zhangsan'  
console.log(others); // {age: 30, city: 'shenzhen'}  

转至 ChauncyWuBlog

Element querySelector和querySelectorAll和matches的使用

1.querySelector

返回第一个匹配的的第一个元素,如果没有返回Null

eg:
var body = document.querySelector('body');

var myDiv = document.querySelector('#myDiv');

var selected = document.querySelector('.selected');

var img = document.body.querySelector('img .button');

2.querySelectorAll

返回匹配的NodeLists.

eg: 
var ems = document.getElementById('myDiv').querySelectorAll('em');

var strongs = document.querySelectorAll('p strong');

3.matchesSelector

Eelement类型新增的方法。接收css 选择符,如果调用元素与该选择符匹配,返回true,否则返回false
目前除IE6-IE8,Firefox/Chrome/Safari/Opera/IE 的最新版本均已实现,但方法都带上了各自的前缀.

function matchesSelector(element,selector){
  if(element.matchesSelector){
    return element.matchesSelector(selector);
  }else if(element.msMatchesSelector){
    return element.msMatchesSelector(selector);
  }else if(element.mozMatchesSelector){
    return element.mozMatchesSelector(selector);
  }else if(element.webkitMatchesSelector){
    return element.webkitMatchesSelector(selector);
  }else{
            ...
  }
}

关于项目中 Git 分支理解

现在公司开发的过程中分三种分支:
develop 开发分支 用于 dev 测试
master 测试分支 用于 sit 测试
release 生产分支 用于 uat 测试

还有四种短期分支,是临时创建之用的,可以合并到主分支上面

  • 功能分支(feature branch)用于开发主功能的 bug
  • 补丁分支(hotfix branch)用于修复紧急的 bug
  • bug修复分支 (bugfix branch) 用于修复日常(当天)的bug
  • 预发分支(release branch)用于开发发版功能的分支

每个公司安排合并分支都会有不同的要求,对分支的实现功能要求也有不同的。

image

git flow A successful Git branching model

系统开发测试 定义 单元测试 集成测试 系统测试 验收测试 回归测试

单元测试:单元测试是对软件中的基本组成单位进行的测试,如一个模块、一个过程等等。它是软件动态测试的最基本的部分,也是最重要的部分之一,其目的是检验软件基本组成单位的正确性。一个软件单元的正确性是相对于该单元的规约而言的。因此,单元测试以被测试单位的规约为基准。单元测试的主要方法有控制流测试、数据流测试、排错测试、分域测试等等。

集成测试:集成测试是在软件系统集成过程中所进行的测试,其主要目的是检查软件单位之间的接口是否正确。它根据集成测试计划,一边将模块或其他软件单位组合成越来越大的系统,一边运行该系统,以分析所组成的系统是否正确,各组成部分是否合拍。集成测试的策略主要有自顶向下和自底向上两种。

系统测试:系统测试是对已经集成好的软件系统进行彻底的测试,以验证软件系统的正确性和性能等满足其规约所指定的要求,检查软件的行为和输出是否正确并非一项简单的任务,它被称为测试的 “ 先知者问题 ” 。因此,系统测试应该按照测试计划进行,其输入、输出和其他动态运行行为应该与软件规约进行对比。软件系统测试方法很多,主要有功能测试、性能测试、随机测试等等。

验收测试:验收测试旨在向软件的购买者展示该软件系统满足其用户的需求。它的测试数据通常是系统测试的测试数据的子集。所不同的是,验收测试常常有软件系统的购买者代表在现场,甚至是在软件安装使用的现场。这是软件在投入使用之前的最后测试。

回归测试:回归测试是在软件维护阶段,对软件进行修改之后进行的测试。其目的是检验对软件进行的修改是否正确。这里,修改的正确性有两重含义:一是所作的修改达到了预定目的,如错误得到改正,能够适应新的运行环境等等;二是不影响软件的其他功能的正确性。

weex 踩坑记

weex踩坑记

weex 是一个基于 Vue, 一端编译三端运行的框架,利用 weex 可以编译出,IOS ,Andriod, Web 的代码,所以组件都是抽象到一个共用组件的程度,很多HTML能使用的标签在 weex上都是不能使用的,一般只能使用 weex 框架上提供的组件,但是这也有例外,所以就会有坑。本文是记录开发weex过程中遇到的坑避免重复踩坑。

  1. 页面加截自动获取 input 焦点
    查了很长时间以为是页面脚本进入组件是触发到焦点,原来 weex 里面组件 input 是有一个属性,autofocus {boolean}:布尔类型的数据,表示是否在页面加载时控件自动获得输入焦点。设置了但是还是在安卓机上存在自动触发焦点,怎办原来点击事件是击穿了页面,添加上 setTimeout 延迟执行即可。

  2. weex 文本溢出省略显示
    我一直以为像Web 页面一样把CSS写成下面的样式就可以了

overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;

这样写后一直不显示,文本省略号,然而并不是这样在 weex 里面 text 组件,原来还有一个属性指定文本行数
lines {number}: 指定文本行数。仅在 <text> 组件中支持。默认值是 0 代表不限制行数。
你需要把 CSS 写成下面这样。

overflow: hidden;
text-overflow: ellipsis;
lines: 1

关于npm run dev和build

npm run XXX是执行配置在package.json中的脚本,比如:
`
"scripts":{

"dev": "node build/dev-server.js",
"build": "node build/build.js",
"unit": "karma start test/unit/karma.conf.js --single-run",
"e2e": "node test/e2e/runner.js",
"test": "npm run unit && npm run e2e",
"lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs"

},
`
只有这里配置了,你才能run,所以不是所有的项目都能npm run dev/build。要了解这些命令做了什么,就要去scripts中看具体执行的是什么代码。这里就像是一些命令的快捷方式,免去每次都要输入很长的的命令(比如unit那行)。

为什么会出现ERROR,就是因为在跑这些对应的脚本文件的时候,可能是某些依赖没有被加载等的。

一般项目都会有build, dev, unit等,从名字上基本能看出来是干什么的。比如上面配置的unit,就是开启karma去跑单元测试,具体测试内容,要去看karma.conf.js;e2e就是end to end的端到端测试;而test则会将单元测试和端到端测试都执行。

有些项目中根据需要,还会配置其他命令,例如自动生成文档,比如这里:

"build:doc": "node ./scripts/build-doc.js",
如果你去build-doc.js中看的话,会发现,这个脚本在遍历所有源文件,解析注释和其他内容,自动生成API文档

script

npm 会在项目的 package.json 文件中寻找 scripts 区域,其中包括npm test和npm start等命令。

其实npm test和npm start是npm run test和npm run start的简写。事实上,你可以使用npm run来运行scripts里的任何条目。

使用npm run的方便之处在于,npm会自动把node_modules/.bin加入$PATH,这样你可以直接运行依赖程序和开发依赖程序,不用全局安装了。只要npm上的包提供命令行接口,你就可以直接使用它们,方便吧?当然,你总是可以自己写一个简单的小程序。

参考文献
参考文献

浏览器核心引擎名称

Navigator.userAgent
1.MSIE IE
2.Gecko FireFox
3.AppleWebkit Chrome Safari
4.Opera Opera
5.khtml Lunix
6.moblie Android IOS

IE 9.0以上 Mozilla 5.0

css居中方法总结

1. 设置子元素宽度,margin:0 auto;

2. 父类设置display:table, 子类设置display:table-cell,vertical-align: middle;

3. 父类设置position:relative, (子类不定宽)

     子类设置position: absolute,
     top:0;
     right:0;
     bottom:0;
     left:0;
     margin: auto;
     子类设置宽度

4. 父类设置text-align:center (子类不定宽)

      父类设置 before 空白区域居中
                     content: '';
                     display: inline-block;
                     height: 100%;
                     vertical-align: middle;
       子类:display: inline-block;

5. css3 flex (子类不定宽)

      父类设置:
                    display: flex;
                    align-items: center;
                    justify-content: center;

6.设置position: fixed,设置

        top: 0;
        right:0;
        bottom:0;
        left: 0;
        margin: auto;
        width: 300px;
        height: 200px;

7. translate (子类不定宽)

      父类设置
       position: relative,
      子类设置
       position: absolute,
       top: 50%;
       left: 50%;
       transform: translate(-50%, -50%)

8.Float 浮云居中

父类
float:left;
width:100%;
overflow:hidden;
position:relative;

子类
clear:left;
float:left;
position: relative;
left:50%;/整个分页向右边移动宽度50%/
text-align:center;

样版例子 地址

Js 全局对象

window 全局window 对象
document window下面的属性
screen 浏览器窗口的参数,尺寸.
navigator 浏览器属性
location 地址属性
history 历史记录属性和方法

webpack devtool 配置选项

在webpack的配置文件中配置source maps,需要配置devtool,它有以下四种不同的配置选项,各具优缺点,描述如下:

devtool选项 配置结果
source-map 在一个单独的文件中产生一个完整且功能完全的文件。这个文件具有最好的source map,但是它会减慢打包文件的构建速度;
cheap-module-source-map 在一个单独的文件中生成一个不带列映射的map,不带列映射提高项目构建速度,但是也使得浏览器开发者工具只能对应到具体的行,不能对应到具体的列(符号),会对调试造成不便;
eval-source-map 使用eval打包源文件模块,在同一个文件中生成干净的完整的source map。这个选项可以在不影响构建速度的前提下生成完整的sourcemap,但是对打包后输出的JS文件的执行具有性能和安全的隐患。不过在开发阶段这是一个非常好的选项,但是在生产阶段一定不要用这个选项;
cheap-module-eval-source-map 这是在打包文件时最快的生成source map的方法,生成的Source Map 会和打包后的JavaScript文件同行显示,没有列映射,和eval-source-map选项具有相似的缺点;
正如上表所述,上述选项由上到下打包速度越来越快,不过同时也具有越来越多的负面作用,较快的构建速度的后果就是对打包后的文件的的执行有一定影响。

参考完文

JavaScript 严格模式的限制

"use strict";
变量必须声明后再使用
函数的参数不能有同名属性,否则报错
不能使用with语句
不能对只读属性赋值,否则报错
不能使用前缀0表示八进制数,否则报错
不能删除不可删除的属性,否则报错
不能删除变量delete prop,会报错,只能删除属性delete global[prop]
eval不会在它的外层作用域引入变量
eval和arguments不能被重新赋值
arguments不会自动反映函数参数的变化
不能使用arguments.callee
不能使用arguments.caller
禁止this指向全局对象
不能使用fn.caller和fn.arguments获取函数调用的堆栈
增加了保留字(比如protected、static和interface)

Forbid certain propTypes React.PropTypes

var Component = createReactClass({
  propTypes: {
    a: PropTypes.any,
    r: PropTypes.array,
    o: PropTypes.object
  },
...
});

I propose a rule that forbids every usage of:

React.PropTypes.object which should be replaced by React.PropTypes.shape
React.PropTypes.array which should be replaced by React.PropTypes.arrayOf

Document 的重要属性和方法

HTMLDocument

可以通过Document实例访问页面.

Document 的属性

Document.childNodes 可以访问子节点
Document.childNodes[0] // <!DOCTYPE>
Document.childNodes[1] // <html></html>节点

Document.documentElement
Document.documentElement // <html></html>节点

Document.doctype
Document.doctype //<!DOCTYPE>
document.doctype.nodeType // 10 DOCUMENT_TYPE_NODE

Document.title
文档的题目

Document.URL
文档的连接

Document.domain
文档域名

Document 的方法

getElementById
按元素id获取

getElementsByTagName
按标签名获取元素

getElementsByName
获取特定的Name获取所有元素

write()
document.write 写脚本到页面

React创建组件的三种方式及其区别 React高阶组件

React创建组件的三种方式及其区别 React高阶组件

React 专注于 view 层,组件化则是 React 的基础,也是其核心理念之一,一个完整的应用将由一个个独立的组件拼装而成。

截至目前 React 已经更新到 v15.4.2,由于 ES6 的普及和不同业务场景的影响,我们会发现目前主要有三种创建 React 组件的写法:

  1. 写法React.createClass ES5
  2. 写法React.Component ES6
  3. 无状态的函数式写法 (纯组件-SFC)

ES5-写法 React.createClass

(createClass也会在react 16中去除,所以不建议使用)

React.createClass不用多说,我们最早使用这个方法来构建一个组件“类”,它接受一个对象为参数,对象中必须声明一个render方法,render返回一个组件实例,下面用一个 SwitchButton 组件的例子来看看React.createClass的具体用法:

 1 var React = require('react');
 2 var ReactDOM = require('react-dom');
 3 
 4 var SwitchButton = React.createClass({
 5   getDefaultProp:function() {
 6     return { open: false }
 7   },
 8 
 9   getInitialState: function() {
10     return { open: this.props.open };
11   },
12 
13   handleClick: function(event) {
14     this.setState({ open: !this.state.open });
15   },
16 
17   render: function() {
18     var open = this.state.open,
19       className = open ? 'switch-button open' : 'btn-switch';
20 
21     return (
22       <label className={className} onClick={this.handleClick.bind(this)}>
23         <input type="checkbox" checked={open}/>
24       </label>
25     );
26   }
27 });
28 
29 ReactDOM.render(
30   <SwitchButton />,
31   document.getElementById('app')
32 );

ES6-写法 React.Component

React 升级到 v0.13 后就支持了 ES6 的class语法,我们可以使用class App extends React.Component{...}的方式创建组件,这也是目前官方推荐创建有状态组件的方式。用 ES6 重写上面 SwitchButton 组件的例子:

 1 import React from 'react'
 2 import { render } from 'react-dom'
 3 
 4 class SwitchButton extends React.Component {
 5   constructor(props) {
 6     super(props)
 7     this.state = {
 8       open: this.props.open
 9     }
10     this.handleClick = this.handleClick.bind(this)
11   }
12 
13   handleClick(event) {
14     this.setState({ open: !this.state.open })
15   }
16 
17   render() {
18     let open = this.state.open,
19       className = open ? 'switch-button open' : 'btn-switch'
20 
21     return (
22       <label className={className} onClick={this.handleClick}>
23         <input type="checkbox" checked={open}/>
24       </label>
25     )
26   }
27 }
28 
29 SwitchButton.defaultProps = {
30   open: false
31 }
32 
33 render(
34   <SwitchButton />,
35   document.getElementById('app')
36 )

与React.createClass创建组件的不同之处:

import
与这里使用了 ES6 的import语句替代require()方法导入模块,其中import {render}可以直接从模块中导入变量名,这种写法更加简洁直观。

初始化 state
React 使用 ES6 的“类”继承实现时,去掉了getInitialState这个 hook 函数,state的初始化放在构造函数方法constructor中声明。

this 绑定
React.Component创建组件时,事件函数并不会自动绑定this,需要我们手动绑定,不然this将不会指向当前组件的实例对象。以下有三种绑定this的方法:

  1. 在constructor中使用bind()进行硬绑定
constructor() {
  this.handleClick = this.handleClick.bind(this);
}
  1. 直接在元素上使用bind()绑定
    <label className={className} onClick={this.handleClick.bind(this)}>

  2. ES6 有个很有用的语法糖:Arrow Function(箭头函数)它可以很方便的使this直接指向class SwitchButton(它的作用等同于大家熟悉的var self = this,但后者会让代码变得混乱,Arrow Function 就很好的解决了这一问题)
    <label className={className} onClick={()=>this.handleClick()}>

无状态的函数式写法(纯组件 SFC)

React.createClass和React.Component都可以用来创建有状态的组件,而 无状态组件 - Stateless Component 是 React 在 v0.14 之后推出的。

它的出现 是因为随着应用复杂度不断提升和组件本数量的增加,组件按各自职责被分成不同的类型,于是有一种只负责展示的纯组件出现了,它的特点是不需要管理状态state,数据直接通过props传入,这也符合 React 单向数据流的**。

对于这种无状态的组件,使用函数式的方式声明,会使得代码的可读性更好,并能大大减少代码量,Arrow Function 则是函数式写法的最佳搭档:

1 const Todo = (props) => (
2   <li
3     onClick={props.onClick}
4     style={{textDecoration: props.complete ? "line-through" : "none"}}
5   >
6     {props.text}
7   </li>
8 )

上面定义的 Todo 组件,输入输出数据完全由props决定,而且不会产生任何副作用。对于props为 Object 类型时,我们还可以使用 ES6 的解构赋值:

1 const Todo = ({ onClick, complete, text, ...props }) => (
2   <li
3     onClick={onClick}
4     style={{textDecoration: complete ? "line-through" : "none"}}
5     {...props}
6   >
7     {props.text}
8   </li>
9 )

无状态组件一般会搭配高阶组件(简称:HOC)一起使用,高阶组件用来托管state,Redux 框架就是通过 store 管理数据源和所有状态,其中所有负责展示的组件都使用无状态函数式的写法。

这种模式被鼓励在大型项目中尽可能以简单的写法 来分割原本庞大的组件,而未来 React 也会面向这种无状态的组件进行一些专门的优化,比如避免无意义的检查或内存分配。所以建议大家尽可能在项目中使用无状态组件。

当然,无状态组件也不是万金油,比如它不支持"ref",原因很简单,因为 React 调用它之前,组件不会被实例化,自然也就没有"ref",(ref和findDOMNode实际上打破了父子组件之间仅通过 props 来传递状态的约定,违背了 React 的原则,需要避免)。

以上三种写法的比较,以及最佳实践

Facebook 官方早就声明 ES6React.Component将取代React.createClass。随着 React 不断发展,React.createClass暴露出一些问题:

相比React.Component可以有选择性的绑定需要的函数,React.createClass会自动绑定函数,这样会导致不必要的性能开销。
React.createClass亲生的 mixin,React.Component不再支持,事实上 mixin 不够优雅直观,替代方案是使用更流行的高阶组件-HOC,如果你的项目还离不开 也可以使用 react-mixin
总的来说:无状态函数式写法 优于React.createClass,而React.createClass优于React.Component。

参考资料相关连接
转载自Peach Blog 地址
原网站译言语文地址 Todd Motto Blog
将 React 组件 由 createClass 重构为 ES6 写法 优化绑定
转载自好道网 地址
无状态组件(Stateless Component) 与高阶组件 地址
三种组件区别 地址
React中函数式声明组件 地址

Git 学习命令与总结

官网下载的

安装包 地址

image

git 命令

git init

把这个目录变成Git可以管理的仓库

git add <file.txt>

把文件添加到仓库

git commit [-m] 参数

把添加的文件推送到Repository, 添加参数[-m]可以填写更新信息

git status

查看当前仓库提交状态

git diff

查看当前仓库文件更改状态

git log

查看当前仓库提交日志

git reset

回到以前的版本,或者选择将来的版本,一般按照 commit ID 操作.

git reflog

记录每一步的操作,可以通过这个命令查找恢复之前的操作.

git checkout

最为常用的两种情形是创建分支和切换分支 教程

git rm

命令git rm用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。

git remote

远程同步
git remote add origin [email protected]:michaelliao/learngit.git (添加远程github仓库)

git push <远程主机名> <本地分支名> : <远程分支名>

把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。

git push -u origin master
上面命令将本地的master分支推送到origin主机,同时指定origin为默认主机,后面就可以不加任何参数使用git push了。

git fetch
同步远程服务主机分支下来本地mirrir进行比较,比较后再merge.

git fetch -prune
同步远程分支与本地分支,把与远程分支不对应的本地分支删除.

git log
查看提交的记录,查看commit的各记录.

commit 3628164fb26d48395383f8f31179f24e0882e1e0
Author: Michael Liao <[email protected]>
Date:   Tue Aug 20 15:11:49 2013 +0800

    append GPL

commit ea34578d5496d7dd233c827ed32a8cd576c5ee85
Author: Michael Liao <[email protected]>
Date:   Tue Aug 20 14:53:12 2013 +0800

    add distributed

commit cb926e7ea50ad11b8f9e909c05226233bf755030
Author: Michael Liao <[email protected]>
Date:   Mon Aug 19 17:51:55 2013 +0800

    wrote a readme file

git log --pretty=oneline
当然了,在实际工作中,我们脑子里怎么可能记得一个几千行的文件每次都改了什么内容,不然要版本控制系统干什么。版本控制系统肯定有某个命令可以告诉我们历史记录,在Git中,我们用git log命令查看

$ git log
commit 3628164fb26d48395383f8f31179f24e0882e1e0
Author: Michael Liao <[email protected]>
Date:   Tue Aug 20 15:11:49 2013 +0800

    append GPL

commit ea34578d5496d7dd233c827ed32a8cd576c5ee85
Author: Michael Liao <[email protected]>
Date:   Tue Aug 20 14:53:12 2013 +0800

    add distributed

commit cb926e7ea50ad11b8f9e909c05226233bf755030
Author: Michael Liao <[email protected]>
Date:   Mon Aug 19 17:51:55 2013 +0800

    wrote a readme file

git log --pretty=oneline
git log命令显示从最近到最远的提交日志,我们可以看到3次提交,最近的一次是append GPL,上一次是add distributed,最早的一次是wrote a readme file。
如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline参数

$ git log --pretty=oneline
3628164fb26d48395383f8f31179f24e0882e1e0 append GPL
ea34578d5496d7dd233c827ed32a8cd576c5ee85 add distributed
cb926e7ea50ad11b8f9e909c05226233bf755030 wrote a readme file

git reset --hard HEAD^
还可以继续回退到上一个版本.

$ git reset --hard 3628164
退回某一个commit Id 的版本.

遇到的问题:

添加文件 fatal: pathspec 'readme.txt' did not match any files 解决方法地址

阮一身git学习
liaoxuefeng git 学习

JavaScript Event 对象 preventDefault()

Event.preventDefault()

在事件里头取消事件的默认动作。
例如下面例子,点击连接不会跳转,只会弹出警告.

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>JS阻止链接跳转</title>
<script type="text/javascript"> 

function stopDefault( e ) { 
if ( e && e.preventDefault ) 
   e.preventDefault(); 
    else 
   window.event.returnValue = false; 

    return false; 
} 

</script> 
</head>
<body>
<a href="http://www.baidu.com" id="testLink">百度</a>

<script type="text/javascript"> 
var test = document.getElementById('testLink'); 
test.onclick = function(e) { 
   alert('我的链接地址是:' + this.href + ', 但是我不会跳转。'); 
   stopDefault(e); 
} 
</script>

</body>
</html>

关于 JavaScript 的继承

继承是 OO **中的重大特性,当然 JavaScript 也实现了这一特性,OO 语言当中都支持两种继承的方法:

  1. 接口继承 意思是高度抽象父类,让子类只继承接口,不需要具体实现。
  2. 实现继承 意思是子类继承之后,有具体的实现方法,或者实现是继承自父类的。

ECMAScript 继承和 JAVA OO 语言那些不一样,只支持实现继承,不支持抽象的接口继承。
而在 ES5 中实现继承都是基于原型链来实现继承的,基本**是利用原型让一个引用类型继承另一个引用类型的属性和方法。先回一下 JavaScript 原型链概念,每个构造函数都有一个原型的对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。如果我们让原型对象等于另一个类型的实例就形成了原型链。

prototype

1. 原型链继承

看一下实现继承的基本方式 (ES5)

    // 构建父类构造函数
    function Father() {
        this.property = true
    }
    // 父类的原型链
    Father.prototype.getFatherValue = function() {
        return this.property
    }
    // 构建子类构造函数
    function Child() {
        this.subproperty = false
    }
    // 子类原型指向父类实例 (继承)
    Child.prototype = new Father()
    Child.prototype.getChildValue = function() { // 添加子类原型链
        return this.subproperty
    }
    var child1 = new Child()
    console.log(child.getFatherValue()) // true 能访问父类函数 父类函数访问父类属性
    console.log(child.getChildValue()) // false 访问子类函数返回子类属性

(ES6) 继承的实现, ES6 有关键字extends定义继承需然,最终使用的还是通过原型链来实现,但是有了语法糖可看性良好了很多。

    class Father {
        constructor() {
            this.property = true
        }
        getFatherValue() {
            return this.property
        }
    }

    class Child extends Father {
        constructor() {
            this.subproperty = false
        }
        getChildValue() {
            return this.subproperty
        }
    }
    var child1 = new Child()
    console.log(child1.getFatherValue()) // true
    console.log(child1.getChildValue()) // false

2. 借用构造函数

使用借用构造函数其实就是,在子类型构造函数的内部调用父类型构造函数。甚至可以在子类给父类传参,用来实现构造函数不会重写子类型的属性。但是借用构造函数并没有继承至父类,调用不了父类的方法,所以只能使用下面组合继承的方式。

(ES5)

    function Father() {
        this.colors = ["red","blue","green"]
    }
    function Child() {
        Father.call(this) // 通过子类调用父类构造函数实现继承
    }

    var instance1 = new Child() // 新建实例时单独创建父类
    instance1.colors.push("black")
    console.log(instance1.colors) // "red,blue,green,black"

    var instance2 = new Child()
    console.log(instance2.colors) // "red, blue, green"
    console.log(instance1.__proto__ === instance2.__proto__) // true 原型链都是指向 Child 构造函数
    console.log(instance1 instanceof Father) // false 而儿实际上原型链没有继承 Father

(ES6) 中借用借用父类的构造函数都是使用关键字 super 来实现的。

    class Father() {
        constructor() {
            this.colors = ["red","blue","green"]
        }
    }
    class Child() extends Father { // extends 的意思是继承 Father 的原型链
        constructor() {
            super()     // 没有 extends 不能使用 super 
        }
    }
    var instance1 = new Child()
    instance1.colors.push("black")
    console.log(instance1.colors) // "red,blue,green,black"
    var instance2 = new Child()
    console.log(instance2.colors) // "red, blue, green"
    console.log(instance1.__proto__ === instance2.__proto__) //true 原型都指向 Child 构造函数
    console.log(instance1 instanceof Father) // true ES6 通过 extends 实现了原型链

3. 组合继承

组合继承是指原型链和借用构造函数的方式结合在一起。

组合继承 (ES5)

    function Father() {
        this.name = name
        this.colors = ["red","blue","green"]
    }
    Father.prototype.sayName = function() {
        console.log(this.name)
    }
    function Child(name, age) {
        // 继承父类属性
        Father.call(this, name)
        this.age = age
    }
    // 子类原型链指向父类
    Child.prototype = new Father()
    Child.prototype.sayAge = function() {
        console.log(this.age)
    }

    var child1 = new Child("Nicholas", 29) // 生成对象
    child1.colors.push("black")
    console.log(child1.colors) //"red, blue, green, black"
    child1.sayName() // "Nicholas" 调用父类方法
    child1.sayAge() // 29 调用子类方法

    var child2 = new Child("Greg", 27)
    console.log(child2.color) //"red, blue, green"
    child2.sayName() // "Greg"
    child2.sayAge() // 27

组合继承 (ES6) 等同于上面 ES5 的写法,而且更简洁易懂。

    // 定义父类
    class Father {
        constructor(name) { // 父类构造函数
            this.name = name
            this.colors = ["red", "blue", "green"]
        }
        sayName() {
            console.log(this.name)
        }
    }
    // 定义子类
    class Child extends Father {
        constructor(name, age) { // 子类构造函数
            super(name) // 调用父类构造函数
            this.age = age
        }
        sayAge() {
            console.log(this.age)
        }
    }

    var child1 = new Child("Nicholas", 29)
    child1.colors.push("black")
    console.log(child1.colors) //"red, blue, green, black"
    child1.sayName() // "Nicholas"
    child1.sayAge() // 29

    var child2 = new Child("Greg", 27)
    console.log(child2.colors) //"red, blue, green"
    child2.sayName() // "Greg"
    child2.sayAge() // 27

4. 原型式继承

原型式继承又称道格拉斯继承,其实就是 Object.create() 方法的实现。通过实例对象的原型来创建新的对象实例。原型式继承是通过原生方法实现的,所以 ES6 暂时没有语法糖支持。

    function object(o) {
        function F(){}
        F.prototype = o
        return new F()
    }

不过使用 Object.create() 传参会相对复杂一些。

    var person = {
        name: "Nicholas",
        friends: ["Shelby", "Court", "Van"]
    }

    var anotherPerson = Object.create(person, {
        name: {
            value: "Greg"
        },
        friends: {
			value: [1,2,3]
		}
    })
    console.log(anotherPerson.name) // "Greg"
    console.log(anotherPerson.friends) // "[1,2,3]"

5.寄生式继承

寄生式继承是通过原型式继承,添加自己宝的属性或者函数。

    function customerCreate(obj) {
        var clone = Object.create(obj) // 通过 Object.create 创建对象
        // 添加自定义函数或者属性
        clone.sayHi = function() {
            console.log('Hi')
        }
        return clone // 返回对象
    }

6.寄生组合式继承

基本原理是通过通过 Object.create() 来实现父类的实例对象,再将子类型的原型继承父类的实例对象。这样创建的原型链,只会调用一次父类构造函数,并且避免在子类上面创建不性格多余的属性。

    function customerInheritCreate(Child, Father) {
        var proto = Object.create(Father.prototype) // 通过 Father 实例创建 Father 原型实例对象
        proto.constructor = Child // 把 proto 的构造函数指向 Child
        Child.prototype = proto // Child 原型链指向 proto 实例
    }

    function Father(name) {
        this.name = name
        this.colors = ["red","blue","green"]
    }
    Father.prototype.sayName = function() {
        console.log(this.name)
    }
    function Child(name, age) {
        Father.call(this, name)
        this.age = age
    }
    customerInheritCreate(Father, Child) // 构建原型链, ES6 extends不合适使用
    Child.prototype.sayAge = function() {
        console.log(this.age)
    }

JavaScript 原型 和 闭包 对比和理解

JavaScript 原型 和 闭包 对比和理解

在我学习JavaScript过程序中总觉得原型和闭包是很相似的东西,总是很难区分什么时候该用什么时候不该使用.而很多项目中很多时候都使用闭包.网上面查阅过很多资料总结以下:
闭包:
优点作用:
1.易于创建对象,能私有化变量与方法..
2.调用实例变量,实例方法效率高,合适高频率操作实例.
3.IIFE立即执行,可以保存模块状态.

缺点:
1.使用过多会占用大量内存.
2.创建对象效率低下.
3.外部引用不利于,垃圾回收,长期占用引用.

原型:
优点作用:
1.易于创建对象,能私有化变量与对象.
2.易于创建实例,创建实例效率高,合适经常创建多实例的原型.
3.能私有化变量与方法.

缺点:
1.调用实例方法效率低下.
2.原型的对象的方法是存在对象的原型链中,寻址速度略慢.

参考 https://segmentfault.com/q/1010000004067464 黒之染
参考 (https://github.com/ClarenceC/knowledge/issues/2)
参考http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html 阮老师教程

原型通常会带着原型链:
image

npm dependencies 和 devDependencies 的区别

  • 使用npm i node_module –save自动更新dependencies字段值;

  • 使用npm i node_module –save-dev自动更新devDependencies字段值;

那 package.json 文件里面的 devDependencies 和 dependencies 对象有什么区别呢?

devDependencies 里面的插件只用于开发环境,不用于生产环境,而 dependencies 是需要发布到生产环境的。

React 基础知识

  1. React 需要加载两个库:React 和 React-DOM,前者是 React 的核心库,后者是 React 的 DOM 适配库。
  2. JSX 语法的最外层,只能有一个节点。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.