这里主要是记录下平时觉得可总结的东东~ 内容都比较浅显~ 如有不足之处,还请帮忙指正 ~
liujinhuan / learnnotes Goto Github PK
View Code? Open in Web Editor NEW日常学习笔记
日常学习笔记
这里主要是记录下平时觉得可总结的东东~ 内容都比较浅显~ 如有不足之处,还请帮忙指正 ~
ES5
中异步模块的规范、实现该规范的是RequireJS<!-- 依赖的模块,提前定义引用;在异步回调中使用依赖 -->
define(['/package/lib'],function(lib){
function foo(){
lib.log("foo")
}
return {
foo
}
})
ES5
中同步模块的规范、实现该规范的是SeaJSdefine(function(require,exports,module){
<!-- 用到依赖的时候再引用;同步使用 -->
var $ = require('jquery')
$('#div').html("hello world")
})
ES5
中node端的模块化规范、通过module.exports
定义module export
和带有名字的输出exports.XXX
exports.hello = function(){
console.log("hello")
}
exports default function (){
console.log("hello")
}
export default {
data:{
},
mouted:function(){
}
}
解决事件的频繁触发,两种解决方案:debounce 防抖、throttle 节流
第一版本
function debounce(func, wait, immediate) {
var timeout, result;
var debounced = function () {
var context = this;
var args = arguments;
if (timeout) clearTimeout(timeout);
// 是否立即执行
if (immediate) {
// 如果已经执行过,不再执行
var callNow = !timeout;
timeout = setTimeout(function(){
timeout = null;
}, wait)
// 返回值的情况、处理this、处理参数event
if (callNow) {
result = func.apply(context, args)
}
} else {
timeout = setTimeout(function(){
func.apply(context, args)
}, wait);
}
return result;
};
// 取消
debounced.cancel = function() {
clearTimeout(timeout);
timeout = null;
};
return debounced;
}
如果你持续触发事件,每隔一段时间,只执行一次事件。
根据首次是否执行以及结束后是否执行,效果有所不同,实现的方式也有所不同。
我们用 leading 代表首次是否执行,trailing 代表结束后是否再执行一次。
// 使用时间戳
function throttle(func, wait) {
var context,args;
var previous = 0;
return function(){
var now = +Date()
context = this;
args = arguments
if(now-previous>wait){
func.apply(context,arg)
previous = now
}
}
}
// 使用定时器
function throttle(func, wait) {
var context,args,timeout;
return function(){
context = this;
args = arguments
if(!timeout){
timeout = setTimeout(function(){
timeout = null
func.apply(context,arg)
},wait)
}
}
}
所以比较两个方法:
第一种事件会立刻执行,第二种事件会在 n 秒后第一次执行
第一种事件停止触发后没有办法再执行事件,第二种事件停止触发后依然会再执行一次事件
双剑合璧
// leading:false 表示禁用第一次执行
// trailing: false 表示禁用停止触发的回调
// 二者不可同时设置
function throttle(func, wait, options) {
var timeout, context, args, result;
var previous = 0;
if (!options) options = {};
var later = function() {
previous = options.leading === false ? 0 : new Date().getTime();
timeout = null;
func.apply(context, args);
if (!timeout) context = args = null;
};
var throttled = function() {
var now = new Date().getTime();
// 禁用第一次的话,上一个的时间就设置为此时
if (!previous && options.leading === false) previous = now;
// 下次触发 func 剩余的时间
var remaining = wait - (now - previous);
context = this;
args = arguments;
// 如果没有剩余的时间了或者你改了系统时间
if (remaining <= 0 || remaining > wait) {
// 清空定时器
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
// 上一个的时间就设置为此时
previous = now;
// 立即执行
func.apply(context, args);
if (!timeout) context = args = null;
} else if (!timeout && options.trailing !== false) {// 禁用停止触发的回调
timeout = setTimeout(later, remaining);
}
};
throttled.cancel = function() {
clearTimeout(timeout);
previous = 0;
timeout = null;
}
return throttled;
}
// array:表示要去重的数组,必填
// isSorted:表示函数传入的数组是否已排过序,如果为 true,将会采用更快的方法进行去重
// iteratee:传入一个函数,可以对每个元素进行重新的计算,然后根据处理的结果进行去重
var array3 = [1, 1, 'a', 'A', 2, 2];
// 第二版
// iteratee 英文释义:迭代 重复
function unique(array, isSorted, iteratee) {
var res = [];
var seen = [];
for (var i = 0, len = array.length; i < len; i++) {
var value = array[i];
var computed = iteratee ? iteratee(value, i, array) : value;
if (isSorted) {
if (!i || seen !== computed) {
res.push(value)
}
seen = computed;
}
else if (iteratee) {
if (seen.indexOf(computed) === -1) {
seen.push(computed);
res.push(value);
}
}
else if (res.indexOf(value) === -1) {
res.push(value);
}
}
return res;
}
console.log(unique(array3, false, function(item){
return typeof item == 'string' ? item.toLowerCase() : item
})); // [1, "a", 2]
typeof
Object.prototype.toString!可以识别至少 14 种类型
写一个 type 函数能检测各种类型的值,如果是基本类型,就使用 typeof,引用类型就使用 toString。此外鉴于 typeof 的结果是小写,我也希望所有的结果都是小写。
// 第二版
var class2type = {};
// 生成class2type映射
"Boolean Number String Function Array Date RegExp Object Error".split(" ").map(function(item, index) {
class2type["[object " + item + "]"] = item.toLowerCase();
})
function type(obj) {
// 一箭双雕
if (obj == null) {
return obj + "";
}
return typeof obj === "object" || typeof obj === "function" ?
class2type[Object.prototype.toString.call(obj)] || "object" :
typeof obj;
}
var shallowCopy = function(obj) {
// 只拷贝对象
if (typeof obj !== 'object') return;
// 根据obj的类型判断是新建一个数组还是对象
var newObj = obj instanceof Array ? [] : {};
// 遍历obj,并且判断是obj的属性才拷贝
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = obj[key];
}
}
return newObj;
}
var deepCopy = function(obj) {
if (typeof obj !== 'object') return;
var newObj = obj instanceof Array ? [] : {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
}
}
return newObj;
}
最近面试的时候有被问过:你对npm了解多少?有发布过包吗? 当时我表示一脸懵逼、其实是有参与过npm包的代码维护,但未曾自己发布过包。。趁着热乎劲儿,在网上找下资料,简单的记录下吧
主要从注册账号、到编写包代码、到发布、到删除的一系列操作吧
sudo npm install verdaccio -g
verdaccio
命令即可运行http://localhost:4873
,如果未发布过包,则会见到如下所示的图npm set registry http://localhost:4873
npm adduser –registry http://localhost:4873
// 创建测试文件夹
mkdir npmtest
// 初始化项目,一路回车即可
npm init
// 创建index.js文件,内容如下
!function(){
console.log(`这是引入的包入口`)
}()
// 发布
npm publish
// 期间可能会遇到提示未登录的错误信息,重新登录下即可,输入userName 和 password 和 email
npm login –registry http://localhost:4873
// 创建测试目录
mkdir test
// 初始化项目,一路回车
npm init
// 安装我们自己的包依赖,可以在package.json文件中看到
npm install npmtest@1.0.0 --save-dev
// 编写测试文件index.js,内容如下
var f = require('npmtest')
// 执行测试文件,结果如下图所示就OK了
node index.js
bundle
,然而随着项目额逐渐扩大,文件数量将急剧增加,不经意间使得打包文件过大而造成应用加载的缓慢。按需加载
Code Splitting
(提倡的是将代码分块chunk
,通过定义一些分割点
来实现分块,从而实现按需加载。)1. 分析产生`慢`的原因
2. 知道为什么`慢`,但是如何解决呢?
3. 知道了解决办法,可是为什么这么做就能实现按需加载呢?
1. ES6的import()函数为什么可以实现动态导入
2. ES6的模块加载机制
3. webpack模块化原理
<!-- 甚至还要了解更多相关的信息 -->
主要参考的是es6官网、webpack官网、react官网等;
针对上述的问题1,可以参考另一篇《ECMAScript 6 入门》学习笔记
引擎处理时机 | 参数 | 加载方式 | 说明 | |
---|---|---|---|---|
import语句 | 编译时 | 模块位置 | 静态加载 | 利于编译器提高效率、但不能条件加载 |
import()函数 | 运行时 | 模块位置 | 动态加载 | 可以运行时、条件加载 |
针对上述的问题2,可以参考另一篇《ECMAScript 6 入门》学习笔记
问题3还在学习中[囧]
import React from 'react';
export default class Bundle extends React.Component {
state = {
mod: null
}
componentWillMount() {
console.log("Bundle---,",this.props)
this.load(this.props);
}
componentWillReceiveProps(nextProps) {
if (nextProps.load !== this.props.load) {
this.load(nextProps);
}
}
// 更改 load 方法为异步函数
async load(props) {
this.setState({
mod: null
});
/*
使用 props.load() 返回的是一个 promise
*/
const mod = await props.load();
this.setState({
mod: mod.default ? mod.default : mod
});
}
render() {
return this.state.mod ? this.props.children(this.state.mod) : null;
}
}
import React from 'react';
import Bundle from './Bundle';
// 默认加载组件,可以直接返回 null
const Loading = () => <div>Loading...</div>;
/*
包装方法,第一次调用后会返回一个组件(函数式组件)
由于要将其作为路由下的组件,所以需要将 props 传入
*/
const lazyLoad = loadComponent => props => (
<Bundle load={loadComponent}>
{Comp => (Comp ? <Comp {...props} /> : <Loading />)}
</Bundle>
);
export default lazyLoad;
import React from 'react'
import { Route } from 'react-router-dom'
import lazyLoad from '../lazyLoad';
<!--静态加载方式-->
// import GameNetwork from '../containers/gameNetwork'
<!--动态加载方式-->
const GameNetwork = lazyLoad(() => import('../containers/gameNetwork'));
<!--N多其他路由定义-->
export default class Routes extends React.Component {
render() {
let routes = (
<div className="view">
<!--N多其他路由配置-->
<Route path="/gameNetwork.html" component={GameNetwork}/>
</div>
)
return routes
}
}
<!-- 省略了详细配置 -->
module.exports = {
entry: [
'./src/index.js'
],
output: {
path: resolve('output'),
filename: 'js/[name].[chunkhash:5].js' ,
publicPath: '',
chunkFilename: 'js/[name].[chunkhash:5].chunk.js'
},
}
module.exports.plugins.push(
// webpack打包分析图、需要的时候可以打开注释
new BundleAnalyzerPlugin({ analyzerPort: 8919 })
)
一个1.8M
文件变成了90多K的main和84k的chunk
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.