mamba-1024 / myblog Goto Github PK
View Code? Open in Web Editor NEW创建自己的blog--在Issues中总结一些基础的知识点和工作中的一些心得
创建自己的blog--在Issues中总结一些基础的知识点和工作中的一些心得
props
发生了变化,如果子组件的数据请求依赖了props
,那么组件就需要重新请求数据。Boolean
值react 16.3 版本删除了
componentWillMount()
componentWillReceiveProps(nextProps)
componentWillUpdate(nextProps, nextState)
useEffect
effects的心智模型和componentDidMount
以及其他生命周期函数式不同的。它的心智模型更接近于状态同步,而不是响应生命周期事件
react Hooks
性能优化:
rerender次数
。当父组件重新属性更新触发重新渲染的时候,子组件也会重新渲染
memo
将子组件包一下。props
传给了子组件是,对子组件只使用memo
是不行的,我们需要将父组件的方法通过useCallback
钩子包一下,同时需要将钩子的依赖设置为[]
空依赖。rerender复杂度
。使用memoize-one
,来减少数据计算,如果入参不发生变化的话
// 在上一次render后,如果参数没有发生改变,memoize-one 会重复使用上一次的返回结果
const filterList = this.filter(this.props.list, this.state.filterText);
我们可以说
useEffect
和useCallback
是有返回值的,它的返回称之为memoize
,它可以根据钩子的第二个参数(依赖数组),来确定是否重新执行钩子中的函数。
useCallback: 不会随着组件更新而重新创建callback方法
根据提供的目标浏览器,智能添加css前缀,js的polyfill,来兼容浏览器。
browserslist
的组件只要package.json
配置了browserslist
对象,需要的组件将自动匹配到并使用,也可以配置到具体的组件参数上
{
'browserslist': [
'> 1%', // 全球超过1%人使用的浏览器
'last 2 version', // 所有浏览器兼容到最后两个版本
'Firefox > 20', // 指定浏览器的版本范围
]
}
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
将数组转存为object
,数组的 value 作为 object 的 key,数组的下标作为 object 的 value,
然后去使用 for in 遍历 object,只用 in 判断 value 是否在 object 中。
附 in使用说明
var twoSum = function(nums, target) {
let result = {};
let length = nums.length;
for (var i = 0; i < length; i++) {
let difference = target - nums[i];
if (difference in result) {
return [result[difference], i]
}
result[nums[i]] = i;
}
};
web前端性能优化之雅虎35条军规
ES全称ECMAScript,ECMAScript是ECMA制定的标准化脚本语言。
通常我们前端拿到后端给的金额数据都是保留两位小数的字符串
此时就需要我们把它转为市面上标准的千分位显示格式
例如:将金额字符串转化为千分的逗号分隔形式 "1,000,000.00"
function toThousands (price: string) {
if(price) {
return price.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")
} else {
return ''
}
}
``
以前别人问我这个问题的时候,起初一时间还是不知道怎么回答,不过仔细想想,这个问题涉及的东西还是蛮多的。如果是自己的话,估计也回答不好。。。
理解JavaScript的环境
在RN中有时候需要为Image组件添加点击事件,但是Image本身又是不支持的,所以我们常用
TouchableWithoutFeedback
TouchableOpacity
TouchableHighlight
将Image
组件包括一下,将onPress
事件加到上面。
本组件用于封装视图,使其可以正确响应触摸操作。当按下的时候,封装的视图的不透明度会降低。
不透明度的变化是通过把子元素封装在一个Animated.View中来实现的,这个动画视图会被添加到视图层级中,少数情况下有可能会影响到布局。
此组件与TouchableHighlight的区别在于并没有额外的颜色变化,更适于一般场景。)
renderButton: function() {
return (
<TouchableOpacity onPress={this._onPressButton}>
<Image
style={styles.button}
source={require('./myButton.png')}
/>
</TouchableOpacity>
);
},
除非你有一个很好的理由,否则不要用这个组件。所有能够响应触屏操作的元素在触屏后都应该有一个视觉上的反馈(然而本组件没有任何视觉反馈),这也是为什么一个"web"应用总是显得不够"原生"的主要原因之一。
注意TouchableWithoutFeedback只支持一个子节点(不能没有子节点也不能多于一个)。如果你希望包含多个子组件,可以用一个View来包装它们。
常见的使用场景比如想实现点击空白处触发某个操作,那么就可以把空白部分用TouchableWithoutFeedback包起来,或者绝对定位覆盖住。
本组件用于封装视图,使其可以正确响应触摸操作。当按下的时候,封装的视图的不透明度会降低,同时会有一个底层的颜色透过而被用户看到,使得视图变暗或变亮。
在底层实现上,实际会创建一个新的视图到视图层级中,如果使用的方法不正确,有时候会导致一些不希望出现的视觉效果。譬如没有给视图的backgroundColor显式声明一个不透明的颜色。
注意TouchableHighlight只支持一个子节点(不能没有子节点也不能多于一个)。如果你希望包含多个子组件,可以用一个View来包装它们。
<input type="file" accept=".csv" />
<input type="file" accept="application/vnd.ms-excel" />
<input type="file" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
<input type="file" accept="text/plain" />
<input type="file" accept="image/jpeg" /> image/png
<input type="file" accept="text/html" />
<input type="file" accept="video/*" />
<input type="file" accept="audio/*" />
<input type="file" accept=".pdf" />
HTTP协议(HyperText Transfer Protocol,超文本传输协议):是客户端浏览器或者其他程序与web服务器之间的应用层通信协议
HTTPS协议(HyperText Transfer Protocol over Secure Socket Layer):可以理解为HTTP+SSL/TLS,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要 SSL,用于安全的 HTTP 数据传输。
SSL(Secure Socket Layer,安全套接字层):1994年为 Netscape 所研发,SSL 协议位于 TCP/IP 协议与各种应用层协议之间,为数据通讯提供安全支持
TLS(Transport Layer Security,传输层安全):其前身是 SSL,它最初的几个版本(SSL 1.0、SSL 2.0、SSL 3.0)由网景公司开发,1999年从 3.1 开始被 IETF 标准化并改名,发展至今已经有 TLS 1.0、TLS 1.1、TLS 1.2 三个版本。SSL3.0和TLS1.0由于存在安全漏洞,已经很少被使用到。TLS 1.3 改动会比较大,目前还在草案阶段,目前使用最广泛的是TLS 1.1、TLS 1.2。
实际使用
SSL/TLS的工作过程
CA作为一个公证机构,能确保数字证书的真实性,CA认证一般是要收费的
当客户端去访问一个带有CA认证的Web服务器的时候
服务器返回经过CA认证的数字证书,证书里面包含了服务器的public key
这里服务器发送了一个SSL证书给客户端,SSL 证书中包含的具体内容有:
...
客户端拿到数字证书,用自己浏览器内置的CA证书解密得到服务器的public key
客户端在接受到服务端发来的SSL证书时,会对证书的真伪进行校验
客户端用服务器的public key加密一个用于接下来的对称加密算法的密钥,传给web服务器
因为只有服务器有private key可以解密,所以不用担心中间人拦截这个加密的密钥
服务器拿到这个加密的密钥,解密获取密钥,再使用对称加密算法,和用户完成接下来的网络通信
微信小程序开发时候,使用手机号授权登录,会遇到手机解密失败的情况。
后端抛出错误如下:
javax.crypto.BadPaddingException: pad block corrupted
问题收集:
总结原因:
问题还是处在微信的 sessionKey
上
当我在getPhoneNumber
中使用wx.login
的时候,第一次总是手机号机密失败,第二次可以成功。
解决方案:
在页面 onShow
中先调用一次 wx.login
将临时 code
暂存,然后在 getPhoneNumber
先使用code
,这样就能保证每次sessionKey
是最新的。
div{
width: 100px;
height: 100px;
background: red;
position: relative;
animation: mymove 5s infinite;
-moz-animation: mymove 5s infinite; /* Firefox */
-webkit-animation: mymove 5s infinite; /* Safari and Chrome */
-o-animation: mymove 5s infinite; /* Opera */
}
@keyframes mymove
{
from {top:0px;}
to {top:200px;}
}
@-moz-keyframes mymove /* Firefox */
{
from {top:0px;}
to {top:200px;}
}
@-webkit-keyframes mymove /* Safari 和 Chrome */
{
from {top:0px;}
to {top:200px;}
}
@-o-keyframes mymove /* Opera */
{
from {top:0px;}
to {top:200px;}
}
@keyframes animationname {keyframes-selector {css-styles;}}
undefined,null,Boolean,Number、String
,对象Object、数组Array、函数function 等
,简而言之:栈内存中存放的是基本数据类型值,堆内存中存放引用类型值,引用类型值在内存中的地址存放在栈中,也就是我们常说的对象引用(指针)。
var a = 5;
var b = a;
console.log(a+"---"+b); // 5---5
b = 6; // 这里重新给b赋值,a值并没有改变
console.log(a+"---"+b);// 5---6
var obj = { name: "lisi" };
var obj2 = obj; // 这里是引用赋值,obj和obj2指向同一个对象
console.log(obj.name + "---" + obj2.name); // lisi---lisi
obj2.name = "wangwu";
console.log(obj.name + "---" + obj2.name);//wangwu---wangwu
从上面例子可以看出:在变量复制方面,基本类型和引用类型也有所不同,基本类型复制的是值本身,而引用类型复制的是内存地址。
指一个域下的文档或脚本试图去请求另一个域下的资源
URL 说明 是否允许通信
http://www.domain.com/a.js
http://www.domain.com/b.js 同一域名,不同文件或路径 允许
http://www.domain.com/lab/c.js
http://www.domain.com:8000/a.js
http://www.domain.com/b.js 同一域名,不同端口 不允许
http://www.domain.com/a.js
https://www.domain.com/b.js 同一域名,不同协议 不允许
http://www.domain.com/a.js
http://192.168.4.12/b.js 域名和域名对应相同ip 不允许
http://www.domain.com/a.js
http://x.domain.com/b.js 主域相同,子域不同 不允许
http://domain.com/c.js
http://www.domain1.com/a.js
http://www.domain2.com/b.js 不同域名 不允许
冒泡排序是比较经典的算法之一,也是排序最慢的算法之一。
冒泡排序的基本思路如下(升序排序):
// 冒泡排序
function bubbleSort ( data ) {
var temp = 0;
for ( var i = data.length ; i > 0 ; i -- ){
for( var j = 0 ; j < i - 1 ; j++){
if( data[j] > data[j + 1] ){
temp = data[j];
data[j] = data [j+1];
data[j+1] = temp;
}
}
}
return data;
}
// 运行结果如下:
> var arr = [99,77,87,100, 6, 38, 69, 32, 2, 6, 9, 55, 69];
> bubbleSort(arr);
> [2, 6, 6, 9, 32, 38, 55, 69, 69, 77, 87, 99, 100]
选择排序是一种比较简单直观的排序算法。它的算法**是,从数组的开头开始遍历,将第一个元素和其他元素分别进行比较,记录最小的元素,等循环结束之后,将最小的元素放到数组的第一个位置上,然后从数组的第二个位置开始继续执行上述步骤。当进行到数组倒数第二个位置的时候,所有的数据就完成了排序。
选择排序同样会用到嵌套循环,外循环从数组第一个位置移到倒数第二个位置;内循环从第二个位置移动到数组最后一个位置,查找比当前外循环所指向的元素还要小的元素,每次内循环结束后,都会将最小的值放到合适的位置上。
//选择排序
function selectionSort( data ) {
for( var i = 0; i< data.length ; i++){
var min = data[i];
var temp;
var index = i;
for( var j = i + 1; j< data.length; j++){
if( data[j] < min ){
min = data[j];
index = j;
}
}
temp = data[i];
data[i] = min;
data[index]= temp;
}
return data;
}
// 运行结果如下:
> var arr = [99,77,87,100, 6, 38, 69, 32, 2, 6, 9, 55, 69];
> selectionSort(arr)
> [2, 6, 6, 9, 32, 38, 55, 69, 69, 77, 87, 99, 100]
插入排序是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
插入排序的实现过程:
//插入排序
function insertionSort( data ) {
var len = data.length;
for (var i = 1; i < len; i++) {
var key = data[i];
var j = i - 1;
while ( j >= 0 && data[j] > key) {
data[j + 1] = data[j];
j--;
}
data[j + 1] = key;
}
return data;
}
在运算速度上,冒泡排序是最慢的,插入排序是最快的,我们可以在运行的过程中通过 console.time('sortName') 和 console.timeEnd('sortName') 来看他们的效率如何
本文示例使用的是阿里云的服务器
/usr/share/nginx/html
scp -r /tmp/local_dir username@servername:remote_dir
eg: scp -r ./monitor root@servername:/usr/share/nginx/html/
配置的端口号根据实际情况自己确认,我的示例使用的 801
# add new nginx web server for monitor
server
{
listen 801 default_server;
listen [::]:801 default_server;
server_name _;
root /usr/share/nginx/html/monitor/;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
# location redirect
location / {
try_files $uri $uri/ /index.html;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
servername:801
以上纯属个人实践所得,如有不妥之处还请指教
问题背景:
有时候我们写的代码中会出现元素嵌套,父元素绑定一个事件,子元素也有自己的事件,此时如果我们处理(阻止事件冒泡),就会出现点击子元素的时候同时会触发父元素的事件,往往我们是要规避这种情况的。
自己总结三种方法:
window.event.cancelBubble = true
document.getElementById('childT').addEventListener('click', (e) => {
window.event.cancelBubble = true; // 在原生事件中可以使用
const name = $(e.target).data('name')
console.log('child', name)
}, false)
e.stopPropagation()
$(document)
.on('click', '.parent', (e) => {
const name = $(e.target).data('name')
console.log('parent', name)
})
.on('click', '.child', (e) => {
e.stopPropagation();
const name = $(e.target).data('name')
console.log('child', name)
// 触发子元素的事件中,事件处理完成后,加一个return false,即可阻止父元素事件的触发
// return false;
})
3.在jQuery中使用return false
$(document)
.on('click', '.parent', (e) => {
const name = $(e.target).data('name')
console.log('parent', name)
})
.on('click', '.child', (e) => {
// e.stopPropagation();
const name = $(e.target).data('name')
console.log('child', name)
// 触发子元素的事件中,事件处理完成后,加一个return false,即可阻止父元素事件的触发
return false;
})
几种JavaScript继承方法
让子类的原型指向父类的实例
function Parent () { // 父类构造函数
this.name = "Jarry";
}
Parent.prototype.getName = function () { // 给Parent添加getName的属性方法
console.log(this.name);
}
function Child () { // 定义子类
}
// 每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型"继承"属性。
Child.prototype = new Parent();
var new_child = new Child();
console.log( new_child.getName() ); // Jarry
引入的问题:
1、引用类型的属性被所有实例共享。
function Parent () {
this.names = [ 'Tom', 'Jarry' ];
}
function Child () {
}
Child.prototype = new Parent();
var child1 = new Child();
console.log(child1,name); // [ 'Tom', 'Jarry' ];
child1.names.push( 'Ketong' );
console.log(child1,name); // [ 'Tom', 'Jarry', 'Ketong' ];
console.log(child2.names === child1.names); // true 属于同一个引用
var child2 = new Child();
console.log(child2.name);// [ 'Tom', 'Jarry', 'Ketong' ];
2、在创建 Child 实例的时候,不能向Parent 传参
|
前端请求后端接口的时候,会涉及当前用户信息已经过期的问题。
通常后端定义重定向都是使用 302 状态码,然后附带重定向的地址。但是,
类似于 401、403、500 等状态码都可以在error回调中捕获到,但是 302 状态码是捕获不到的,因为当状态时 302 时,浏览器自行根据redirectUrl进行了跳转,所以无法在 success 或者 error 回调中捕获到这个 302 信息。
针对上面前端无法获取 302 的问题,可以前后端约定一个 401 等等的状态码,然后使用 axios 的拦截器去处理响应。
具体处理方式:
// Add a response interceptor
axios.interceptors.response.use(function (response) {
// Any status code that lie within the range of 2xx cause this function to trigger
// Do something with response data
return response;
}, function (error) {
// Any status codes that falls outside the range of 2xx cause this function to trigger
// Do something with response error
if(error.response.status === 302) {
window.location = '/login';
} else {
return Promise.reject(error);
}
});
天下武功唯快不破...
cli的目的就是为了提高开发效率,把自己常用的React脚手架使用cli来初始化。
记录一下自己cli的心路历程:
新建一个文件夹kt-cli
进入kt-cli文件夹中 执行 npm init
初始化默认配置;
在package.js文件中,需要新增
"bin": {
"kt-cli": "bin/kt-cli.js"
}
npm install commander --save
npm install git-clone --save
npm install shelljs --save
npm install tracer --save
#!/usr/bin/env node
const clone = require("git-clone");
const program = require("commander");
const shell = require("shelljs");
const log = require("tracer").colorConsole();
program.version("1.0.0").description("我的React—cli");
program.command("create [project]").action(function( project) {
log.info("准备生成react模板;");
if (project) {
let pwd = shell.pwd();
log.info(`正在拉取模板代码,下载位置:${pwd}/${project}/ ...`);
clone(
`https://github.com/huangketong/umi-react-admin.git`,
pwd + `/${project}`,
null,
function() {
shell.rm("-rf", pwd + `/${project}/.git`);
log.info("模板建立完成");
}
);
} else {
log.error("正确命令例子:kt-cli create myUmi");
}
});
program.parse(process.argv);
到此我的cli就已经完成了。
接下来就需要把cli发布到npm
上。
使用Mac做开发的时候遇到的一些环境配置问题
二叉树作为一种很基础但是又很重要的数据结构,在某些场景下还是比较重要的。所以掌握二叉树的重要性就不言而喻了。
二叉树是由根节点,左子树,右子树组成,左子树和友子树分别是一个二叉树
举个栗子:
var binaryTree = {
value: 1,
left: {
value: 2,
left: {
value: 4
}
},
right: {
value: 3,
left: {
value: 5,
left: {
value: 7
},
right: {
value: 8
}
},
right: {
value: 6
}
}
}
var preListRec = []; //定义保存先序遍历结果的数组
var preOrderRec = function(node) {
if (node) { //判断二叉树是否为空
preListRec.push(node.value); //将结点的值存入数组中
preOrderRec(node.left); //递归遍历左子树
preOrderRec(node.right); //递归遍历右子树
}
}
preOrderRec(tree);
console.log(preListRec)
var inListRec = []; //定义保存中序遍历结果的数组
var inOrderRec = function(node) {
if (node) { //判断二叉树是否为空
inOrderRec(node.left); //递归遍历左子树
inListRec.push(node.value); //将结点的值存入数组中
inOrderRec(node.right); //递归遍历右子树
}
}
inOrderRec(tree);
console.log(inListRec);
var postListRec = []; //定义保存后序遍历结果的数组
var postOrderRec = function(node) {
if (node) { //判断二叉树是否为空
postOrderRec(node.left); //递归遍历左子树
postOrderRec(node.right); //递归遍历右子树
postListRec.push(node.value); //将结点的值存入数组中
}
}
postOrderRec(tree);
console.log(postListRec);
广度优先遍历是从二叉树的第一层(根结点)开始,自上至下逐层遍历;在同一层中,按照从左到右的顺序对结点逐一访问
实现原理:
使用数组模拟队列,首先将根结点归入队列。当队列不为空时,执行循环:取出队列的一个结点,如果该节点有左子树,则将该节点的左子树存入队列;如果该节点有右子树,则将该节点的右子树存入队列
var breadthList = []; // 定义保存广度遍历结果的数组
var breadthTraversal = function(node) {
if (node) { // 判断二叉树是否为空
var que = [node]; // 将二叉树放入队列 var que = []; que.push(node);
while (que.length !== 0) { // 判断队列是否为空
node = que.shift(); // 从队列中取出一个结点
breadthList.push(node.value); // 将取出结点的值保存到数组
if (node.left) que.push(node.left); // 如果存在左子树,将左子树放入队列
if (node.right) que.push(node.right); // 如果存在右子树,将右子树放入队列
}
}
}
breadthTraversal(tree);
console.log(breadthList);
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.