完美

[学习|工作|博客|交流平台|完美起航]

作者头像zyw3272018.06.20 16:56 

flex弹性布局(一)

flex弹性布局 Flex是Flexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。 任何一个容器都可以指定为Flex布局。 .flex{ display: flex; display: -webkit-flex; /* Safari */ border: none; } <div class="flex"> <div>12</div><div>13</div><div>14</div><div>15</div><div>16</div><div>17</div><div>18</div><div>19</div> </div> 效果如下: note: 设为Flex布局以后,子元素的float、clear和vertical-align属性将失效。 flex-direction row (默认值):主轴为水平方向,起点在左端。 /*水平从左至右排列*/ .flex-direction.row{ flex-direction: row; } <div class="flex flex-direction row"> <div>12</div><div>13</div><div>14</div><div>15</div><div>16</div><div>17</div><div>18</div><div>19</div> </div> 效果如下: row-reverse 主轴为水平方向,起点在右端。 /*效果类似于float:right, 但是row-reverse不是浮动,而元素的排列也不一样,原来左边的排列在右边*/ .flex-direction.row-reverse{ flex-direction: row-reverse; } <div class="flex flex-direction row-reverse"> <div>12</div><div>13</div><div>14</div><div>15</div><div>16</div><div>17</div><div>18</div><div>19</div> </div> 效果如下: column 主轴为垂直方向,起点在上沿。 /*垂直向下排列*/ .flex-direction.column{ flex-direction: column; width: 100px; } <div class="fle

flex 61 1

作者头像zyw3272018.05.31 14:18 

Node.js cluster模块相关笔记

cluster Node.js的单个实例在单个线程中运行。 要利用多核系统,用户有时会想启动一个Node.js进程集群来处理负载。 cluster模块可以轻松创建全部共享服务器端口的子进程。 const cluster = require('cluster'); const http = require('http'); const numCPUs = require('os').cpus().length; if (cluster.isMaster) { console.log(`Master ${process.pid} is running`); // Fork workers. for (let i = 0; i < numCPUs; i++) { cluster.fork(); } cluster.on('exit', (worker, code, signal) => { console.log(`worker ${worker.process.pid} died`); }); } else { // Workers can share any TCP connection // In this case it is an HTTP server http.createServer((req, res) => { res.writeHead(200); res.end('hello world\n'); }).listen(8000); console.log(`Worker ${process.pid} started`); } 运行Node.js,所有的工作进程将共享8000端口 $ node server.js Master 3596 is running Worker 4324 started Worker 4520 started Worker 6056 started Worker 5644 started 请注意,在Windows上,尚不可能在工作进程中设置命名管道服务。 cluster如何工作 使用child_process.fork()方法产生工作进程,以便它们可以通过IPC与父进程通信并来回传递服务器句柄。 cluster模块支持两种分配传入连接的方法。 第一种方法(除Windows以外的所有平台上的默认方法)都是循环法,即主进程在端口上进行侦听,接受新连接并以循环方式在工作进程之间进行分配,其中一些已构建智能避免过载工作进程。 第二种方法是主进程创建侦听套接字并将其发送给感兴趣的工作进程。工作进程然后直接接受传入连接。 理论上,第二种方法应该是最好的。然而,在实践中,由于操作系统调度器的变幻莫测,分配趋于非常不平衡。已经观察到负载超过70%的连接只有两个过程,总共有八个。 因为server.listen()将大部分工作交给了主进程,所以在正常的Node.js进程和集群工作进程之间的行为有三种情况: server.listen({fd:7})因为消息被传递给主进程,父进程中的文件描述符7将被监听,并且该句柄传递给工作进程,而不是监听工作进程的文件描述符7的引用。 server.listen(句柄)明确地监听句柄会导致工作进程使用提供的句柄,而不是与主进程通信。 server.listen(

Cluster 71 1

作者头像zyw3272018.05.25 14:43 

es6之Map对象保存键值对

Map 语法 new Map([iterable]) 参数 iterable Iterable 可以是一个数组或者其他 iterable 对象,其元素或为键值对,或为两个元素的数组。 每个键值对都会添加到新的 Map。null 会被当做 undefined。 描述 一个Map对象以插入顺序迭代其元素 — 一个 for...of 循环为每次迭代返回一个[key,value]数组。 键的相等(Key equality) 键的比较是基于 "SameValueZero" 算法:NaN 是与 NaN 相同的(虽然 NaN !== NaN),剩下所有其它的值是根据 === 运算符的结果判断是否相等。在目前的ECMAScript规范中,-0和+0被认为是相等的,尽管这在早期的草案中并不是这样。有关详细信息,请参阅浏览器兼容性 表中的“value equality for -0 and 0”。 Objects 和 maps 的比较 Object 和 Map 类似的是,它们都允许你按键存取一个值、删除键、检测一个键是否绑定了值。因此(并且也没有其他内建的替代方式了)过去我们一直都把对象当成 Map 使用。不过 Map 和 Object 有一些重要的区别,在下列情况里 Map 会是更好的选择: 一个对象的键只能是字符串或者 Symbols,但一个 Map 的键可以是任意值,包括函数、对象、基本类型。 你可以通过 size 属性直接获取一个 Map 的键值对个数,而 Object 的键值对个数只能手动计算。 Map 是可迭代的,而 Object 的迭代需要先获取它的键数组然后再进行迭代。 Object 都有自己的原型,所以原型链上的键名有可能和对象上的键名产生冲突。虽然 ES5 开始可以用 map = Object.create(null) 来创建一个没有原型的对象,但是这种用法不太常见。 Map 在涉及频繁增删键值对的场景下会有些性能优势。 属性 Map.length 属性 length 的值为 0 。 get Map[@@species] 本构造函数用于创建派生对象。 Map.prototype 表示 Map 构造器的原型。 允许添加属性从而应用于所有的 Map 对象。 Map 实例 所有的 Map 对象实例都会继承 Map.prototype。 属性 Map.prototype.constructor 返回一个函数,它创建了实例的原型。默认是Map函数。 Map.prototype.size 返回Map对象的键/值对的数量。 方法 Map.prototype.clear() 移除Map对象的所有键/值对 。 Map.prototype.delete(key) 移除任何与键相关联的值,并且返回该值,该值在之前会被Map.prototype.has(key)返回为true。之后再调用Map.prototype.has(key)会返回false。 Map.prototype.entries() 返回一个新的 Iterator 对象,它按插入顺序包含了Map对象中每个元素的 [key, value] 数组。 Map.prototype.forEach(callbackFn[, thisArg]) 按插入顺序,为 Map对象里的每一键值对调用一次callbackFn函数。

Map 53 3

作者头像zyw3272018.05.23 18:13 

TypeScript学习笔记(一)

TypeScript TypeScript是JavaScript类型的超集,它可以编译成纯JavaScript。 TypeScript可以在任何浏览器、任何计算机和任何操作系统上运行,并且是开源的。 安装 # 全局安装typescript npm install -g typescript 接口声明 // 声明一个接口 export default interface Sociality { makeFriend():Boolean doGame():void } 类的声明并导出 // 引入接口 import Sociality from './Sociality'; // 声明一个类,实现Sociality接口 export default class Person implements Sociality { // 声明私有变量name,string类型 private name:string // 声明私有变量age,number类型 private age:number // 声明私有变量sex,number类型 private sex: number // 构造函数 constructor(name:string, age:number, sex:number) { this.name = name; this.age = age; this.sex = sex; } // 公开的方法声明,返回值string public getName():string { return this.name; } // 公开的方法声明,返回值number public getAge():number { return this.age; } // 公开的方法声明 public getSex():number { return this.sex; } // 实现接口方法 makeFriend():boolean { return true; } // 实现接口方法 doGame():void { console.log('我们在做游戏'); } } 类的继承 // 引入Person类 import Person from './Person'; // extends关键字实现继承 export default class Girl extends Person { private high:number constructor(name:string, age: number) { super(name, age, 1); } public setHigh(high: number):void { this.high = high; } public getHigh():number { return this.high; } } 编译生成.d.ts文件 tsc -d Girl.ts #

TypeScript 57 1

作者头像zyw3272018.05.22 11:19 

npm包的制作与发布使用

制作npm包的步骤 注册npm账户 npm adduser 或者登陆npm官网注册 登陆npm账户 npm login 编写npm包 初始化package.json并配置 npm init { "name": "包名", "version": "版本号", "description": "描述", "main": "入口文件", "scripts": { "test": "配置测试" }, // 配置git仓库 "repository": { "type": "git", "url": "git仓库地址" }, "keywords": [ "关键字" ], "author": "", "license": "MIT", "dependencies": { } } 发布 npm publish # 指定标签beta npm publish --tag beta 删除 npm unpublish --force 包名 命令行工具包的制作 { "name": "工具名称", "version": "版本号", "description": "描述", "bin": { "命令名称": "命令入口文件" }, "author": "zengyuwen", "license": "MIT" } 代码编写 #!/usr/bin/env node // 获取命令行参数 const arguments = process.argv.splice(2); 代码示例 命令行工具 package.json { "name": "cli", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "bin": { "my-cli": "./index.js" }, "author": "", "license": "ISC" } index.js #!/usr/bin/env node // 获取命令行参数 const arguments = process.argv.splice(2); // 参数解析成数组 function parse(arguments) { return arguments.map(function(value) { if (/^-+/.test(value)) { return value.replace(/^-+/, ''); } return value; }); } // 参数解析成键值对 function parseObj(arguments) { let result = []; for (le

npm 84 0

作者头像zyw3272018.05.22 09:32 

React、Redux和redux-thunk的简单应用

react-redux、redux connect、Provider,createStore 用法 // redux/index.js const ADD = 'add'; const SUB = 'sub'; export function counter(state = 0, action) { switch(action.type) { case ADD: return state + 1; case SUB: return state - 1; default: return state; } } // action export function add() { return {type: ADD}; } // action export function sub() { return {type: SUB}; } // index.js 入口 import React from 'react'; import ReactDOM from 'react-dom'; import App from './App' import {counter} from './redux/index'; import {createStore} from 'redux'; import {Provider} from 'react-redux'; let store = createStore(counter); // 通过props传递store ReactDOM.render( <Provider store={store}> <div> <App /> </div> </Provider> , document.getElementById('root') ); // App.js import react from 'react' import {connect} from 'react-redux' import {add, sub} from './reduxs/index' class App extends react.Component { render() { return ( <div> <span>{this.props.num}</span> <button onClick={this.props.add}>add</button> <button onClick={this.props.sub}>sub</button> </div> ); } } const MapStateToProps = (state) => { return {num}; } const ActionCreator = {add,

React、Redux 74 1

作者头像zyw3272018.05.21 15:41 

JavaScript封装、继承和多态实现

封装(概念) 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。封装是面向对象的特征之一,是对象和类概念的主要特性。 简单的说,一个类就是一个封装了数据以及操作这些数据的代码的逻辑实体。在一个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。 继承(概念) 继承是指可以让某个类型的对象获得另一个类型的对象的属性的方法。它支持按级分类的概念。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。 通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。继承概念的实现方式有二类:实现继承与接口继承。实现继承是指直接使用基类的属性和方法而无需额外编码的能力;接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力; 多态 多态就是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。 封装 es5封装 function Person(name, sex, age) { if (!(this instanceof Person)) { return new Person(name, sex, age); } this.name = name; this.sex = sex || 'female'; this.age = age || 0; this.walk = function() { if (this.age 2 && this.age < 4) { return console.log('我会走路了'); } return console.log('走路'); } this.study = function (skill) { console.log('学习' + skill); } this.introduce = function () { console.log(`我是${this.name},我是一个${this.sex === 'male' ? "男" : "女"}孩,今年${this.age}岁了。`); } } // 调用方式 // new关键字创建实例 var p = new Person('小名', 'male', 10); // 直接调用创建 var p1 = Person('小红', 'female', 9); p.walk(); // 走路 p1.study('游泳'); // 学习游泳 p.introduce();// 我是小名,我是一个男孩,今年10岁了。 p1.introduce();// 我是小红,我是一个女孩,今年9岁了。 原型

封装、继承、多态 86 2

作者头像zyw3272018.05.21 11:29 

es6新类型之Symbol学习笔记(二)

Symbol 全局注册Symbol实现Symbol的共享 使用Symbol()函数的上述语法不会创建整个代码库中可用的全局Symbol。 要创建跨文件甚至跨域的Symbol(每个域都有自己的全局作用域),请使用Symbol.for()和Symbol.keyFor()方法设置和检索全局符号注册表中的符号。 在对象上查找Symbol属性 Object.getOwnPropertySymbols()方法返回一个符号数组,并允许您在给定对象上查找符号属性。 请注意,每个对象都没有自己的符号属性进行初始化,因此除非您已经在对象上设置符号属性,否则此数组将为空。 属性 Symbol.length 长度属性值为0 Symbol.prototype 表示Symbol构造函数的原型 内置符号 除了自己的符号之外,JavaScript还有一些内置的符号,代表了内部语言行为,这些符号在ECMAScript 5以及之前没有向开发者公开。 这些符号可以使用以下属性进行访问: Iteration symbols Symbol.iterator 返回对象的默认迭代器,通常使用for ... of Symbol.asyncIterator 返回对象的AsyncIterator,通常使用 for await of 正则表达式符号 Symbol.match 与字符串匹配的方法,也用于确定对象是否可用作正则表达式。 由String.prototype.match()使用。 Symbol.replace 一种替换字符串的匹配子字符串的方法。通常使用String.prototype.replace()。 Symbol.search 返回与正则表达式匹配的字符串中的索引的方法。通常使用String.prototype.search()。 Symbol.split 在匹配正则表达式的索引处拆分字符串的方法。 通常使用String.prototype.split()。 其他符号 Symbol.hasInstance 确定构造函数对象是否将对象识别为其实例的方法。通常使用instanceof。 Symbol.isConcatSpreadable 一个布尔值,指示对象是否应平铺到其数组元素。 通常使用Array.prototype.concat()。 Symbol.unscopables 一个对象的值,其自己的和继承的属性名称被排除在关联对象的with环境绑定之外。 Symbol.species 用于创建派生对象的构造函数。 Symbol.toPrimitive 将对象转换为原始值的方法。 Symbol.toStringTag 用于默认描述对象的字符串值。 通常使用Object.prototype.toString()。 方法 Symbol.for(key) 用给定键搜索现有符号,如果找到则返回它。 否则,使用该键在全局符号注册表中创建一个新符号。 Symbol.keyFor(sym) 从全局符号注册表中为给定符号检索共享符号密钥。 Symbol prototype(符号原型) 所有符号都从Symbol.prototype继承。 属性 Symbol.prototype.constructor 返回创建实例原型的函数。 这是默认的符号功能。 方法 Symbol.prototy

Symbol 60 2

作者头像zyw3272018.05.20 22:44 

redux与redux-thunk的使用

redux redux是一个可预测的状态容器,(区别于Wordpress framework - Redux Framework) 它可以帮助您编写在不同环境(客户端,服务器和本地)中运行一致并且易于测试的应用程序。 最重要的是,它提供了出色的开发者体验,例如结合时间旅行调试器进行实时代码编辑。 你可以结合react一起使用redux。或者其他任何的视图库,redux很小,包括依赖仅仅2kb。 安装 npm install --save redux # 补充包 # 也许你还要和react一起使用,并且需要开发工具 npm install --save react-redux npm install --save-dev redux-devtools 例子 import { createStore } from 'redux' /** * 这是一个reducer,它是一个具有(state,action)=>状态签名的纯函数。 * 它描述了动作如何将状态转换为下一个状态。 * 状态的形状取决于你:它可以是一个基元,一个数组,一个对象, * 甚至是Immutable.js数据结构。 唯一重要的部分是你应该 * 不改变状态对象,但如果状态改变则返回一个新的对象。 * 在这个例子中,我们使用`switch`语句和字符串,但是你可以使用一个帮助器 * 遵循不同的约定(如功能图),如果它适合你的项目。 */ function counter(state = 0, action) { switch (action.type) { case 'INCREMENT': return state + 1 case 'DECREMENT': return state - 1 default: return state } } // 创建一个持有应用状态的Redux store。 // 他的api { subscribe, dispatch, getState }. let store = createStore(counter) // 你可以通过subscribe()来更新ui来响应状态的改变。 // 通常你会使用视图绑定库 (比如:React-Redux) 比起直接用 subscribe() 。 // 但是,将当前状态保存在localStorage中也可能非常方便。 store.subscribe(() => console.log(store.getState()) ) // 改变内部状态的唯一方法是发送一个action。 // 这些动作可以被序列化,记录或存储,并在以后重播。 store.dispatch({ type: 'INCREMENT' }) // 1 store.dispatch({ type: 'INCREMENT' }) // 2 store.dispatch({ type: 'DECREMENT' }) 您不需要直接改变状态,而是使用称为操作的简单对象指定想要发生的突变。然后编写一个称为reducer的特殊函数来决定每个操作如何转换整个应用程序的状态。 如果您用过Flux,那么您需要了解一个重要的差异。 Redux没有分派器或支持许多store。相反,只有一个store具有单一根reducer函数。随着您的项目的扩展,您不必添加store,

redux 70 0

作者头像zyw3272018.05.20 21:50 

React、Fiux与redux的学习笔记

React React 是一个 View 层的框架,用来渲染视图,它主要做几件事情: 组件化利用 props 形成单向的数据流根据 state 的变化来更新 view利用虚拟 DOM 来提升渲染性能 前面说到 React 能够根据 state 的变化来更新 view,一般来说引起 state 变化的动作除了来自外部(如服务器),大部分都来自于页面上的用户活动,那页面上的用户活动怎样对 state 产生作用呢?React 中每个组件都有 setState 方法用于改变组件当前的 state,所以可以把更改 state 的逻辑写在各自的组件里,但这样做的问题在于,当项目逻辑变得越来越复杂的时候,将很难理清 state 跟 view 之间的对应关系(一个 state 的变化可能引起多个 view 的变化,一个 view 上面触发的事件可能引起多个 state 的改变)。我们需要对所有引起 state 变化的情况进行统一管理,于是就有了 Flux。 Flux Flux 是一种应用架构,或者说是一种思想,它跟 React 本身没什么关系,它可以用在 React 上,也可以用在别的框架上。前面说到 Flux 在 React 中主要用来统一管理引起 state 变化的情况。Flux 维护着一个或者多个叫做Store的变量,就像 MVC 里面的 Model,里面存放着应用用到的所有数据,当一个事件触发时 ,Flux 对事件进行处理,对 Store 进行更新,当 Store 发生变化时,通常是由应用的根组件(也叫 controller view)去获取最新的 store,然后更新 state,之后利用 React 单向数据流的特点一层层将新的 state 向下传递实现 view 的更新。这里的 controller view 可以有多个也可以不是根组件,但是这样数据流维护起来就比较麻烦。 Flux 的思维模型如下: Flux 主要包括四个部分,Dispatcher、Store、View、Action,其中 Dispatcher 是 Flux 的核心枢纽,它相当于是一个事件分发器,将那些分散在各个组件里面的逻辑代码收集起来,统一在 Dispatcher 中进行处理。完整的 Flux 处理流程是这样的:用户通过与 view 交互或者外部产生一个 Action,Dispatcher 接收到 Action 并执行那些已经注册的回调,向所有 Store 分发 Action。通过注册的回调,Store 响应那些与他们所保存的状态有关的 Action。然后 Store 会触发一个 change 事件,来提醒 controller-views 数据已经发生了改变。Controller-views 监听这些事件并重新从 Store 中获取数据。这些 controller-views 调用他们自己的 setState() 方法,重新渲染自身以及组件树上的所有后代组件。使用 Flux 有个好处就是我只需要用 action 对象向 Dispatcher 描述当前的事件就可以执行对应的逻辑,因为 Dispatcher 是所有 Action 的处理中心,即使没有对应的事件发生,我们也可以“伪造”一个出来,非常利于测试。 Redux Redux 的作用跟 Flux 是一样的,它可以看作是 Flux 的一种实现,但是又有点不同,具体的不同总结起来就是: Redux 只有

React 69 2

a6bfb44cbd5549740eb36647f36ef83a