koala-coding / day-day-up Goto Github PK
View Code? Open in Web Editor NEW每天进步一点点,记录每天在公司的一个小收获,一年后你回顾肯定收获了很多,哪怕是你知道了一个新函数,甚至一个新单词都可以。也算是一个个人成长秘籍吧
License: Apache License 2.0
每天进步一点点,记录每天在公司的一个小收获,一年后你回顾肯定收获了很多,哪怕是你知道了一个新函数,甚至一个新单词都可以。也算是一个个人成长秘籍吧
License: Apache License 2.0
看数据结构视频讲解1小时半,背单词100个。读课文几篇。coding时间无。
今日计划完成
1.深蹲50个,
2.投递简历,和hr沟通。获得一个面试机会。
3.背单词100个
4.写成考作业 占据了四个小时
5.读文章2篇。
6.俯卧撑15个。有酸痛感 所以减少。
今天遇到一个需求,已知月份,得到这个月的第一天和最后一天作为查询条件查范围内的数据
new Date(year, month, date, hrs, min, sec)
,new Date可以接受这些参数创建一个时间对象
其中当我们把 date
设置为 0
的时候,可以直接通过 getDate()
获取到最后一天的日期然后得到我们要的最后一天
new Date(2019, 12, 0).getDate() // 31
new Date(2018, 2, 0).getDate() // 28
// 根据这个我们可以得到一个方法
function getMonthLength(month) {
const date = new Date(month)
const year = date.getFullYear()
// 月份是从 0 开始计算的
const _month = date.getMonth() + 1
return new Date(year, _month, 0).getDate()
}
参考文章
一条sql查询语句在mysql数据库中具体是怎么执行的?
SET的方法和属性
add 添加
has 查询
delete 删除
clear 清除
size 长度/大小
forEach 遍历(第一个参数和第二个参数相同)
Map的方法和属性
set 设置,添加
has 查询
delete 删除
clear 清除
size 长度/大小
forEach 遍历
↑↑↑ 接昨天
从图中我们可以看出 MySQL 可以分为 Server 层和存储引擎层两部分。
运行 sql 语句的第一步就是连接数据库。连接器就是负责与客户端建立连接、获取权限、维持和管理连接。
连接器在 TCP 握手后,开始认证身份。
开始连接时,验证用户名和密码,如果验证不通过,服务器会收到
Access denied for user
的错误返回。
如果验证通过,连接器会到权限表中查出拥有的权限。
此次连接查到的权限在这次连接失效前一直有效,不会因为权限的更改而受到影响。
连接完成后,如果一直没有对数据库进行操作,则本次连接处于空闲状态。
show processlist
查看所有连接,command
表示连接状态,sleep
表示空闲
客户端如果太长时间没有请求数据库,连接器会自动断开,默认为8小时,可以通过
wait_timeout
自定义。
连接断开后,客户端再次发送请求,会受到错误提醒:
Lost connection to MySQL server during query
, 需要重新连接服务器。
长连接 : 数据库连接成功后,客户端持续有请求,使用同一个连接。
短连接 : 一次连接只是执行几次 sql 语句就断开,下次执行再重新创建一个。
由于建立连接过程比较复杂,所以在使用中要尽量减少连接次数,尽量使用长连接。
全部使用长连接,由于 mysql 在执行过程中临时使用的内存是保存在连接对象中的,只有在链接断开的时候才会释放,因此mysql 占用内存会涨的特别快。所以长连接累积下来,会导致内存占用太大,被系统强行杀掉(OOM),mysql 异常重启。
解决方案:
- 定期断开长连接。使用一段时间后,或者在执行了一个占用内存大的查询后,断开连接,之后查询时再重连。
- mysql 5.7 或 以后的版本,可以执行
mysql_reset_connection
来初始化连接资源。不需要重新连接,会将连接恢复到刚创建完的状态。
连接数据库后,需要先查询缓存。
如果之前执行过这条查询语句,查询结果可能会以 key-value 的形式保存在内存中。key 是查询的语句, value 是查询到的数据。查询缓存会直接把 value 返回给客户端。
如果查询语句不在查询缓存中,会继续往下执行,获取到的新的查询结果会被存入到查询缓存中。
query_cache_type
设置为 DEMAND
, 这样就不适用查询缓存了SQL_CACHE
指定某一条语句是否使用查询缓存 select SQL_CACHE * from table
Tou have an error in your SQL syntax
当表中有多个索引的时候,优化器会决定 sql 语句使用哪个索引
当查询语句有多表关联时,决定各个表的连接顺序
mysql> select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
执行 sql 语句时,先判断对这个表有没有查询的权限,没有权限会返回没有权限的错误。如果有权限就继续执行,使用存储引擎,
JavaScript 是一种基于对象的语言,但是由于语法中没有 ==class== (类),所以它不是一种真正的面向对象编程语言。
假设把人看成一个对象,他拥有 "姓名" 、 "性别" 、 "年龄" 等属性。
let person = {
name: "",
sex: "",
age: ""
}
按照以上方式创建 Bob 和 Mary 两个人
let person1 = {
name: "Bob",
sex: "man",
age: 18
};
let person2 = {
name: 'Mary',
sex: 'woman',
age: 17
};
这种方法特别的低效,而且 Bob、Mary 和 person原型 之间没有任何关联
通过函数的方式传入参数,并返回对象
function person(name, sex, age) {
return {
name, sex, age
}
}
let person1 = person("Bob", "man", 18);
let person2 = person("Mary", "woman", 17);
这种方法虽然不用一个一个创建对象,但是他们之间没有内在联系,不能反映是统一个原型对象的实例。
构造函数,即在一个普通函数内部使用 ==this== , 然后对该函数使用 ==new== 运算符,生成实例。
function Person(name, sex, age) {
this.name = name;
this.sex = sex;
this.age = age;
}
let person1 = new Person("Bob", "man", 18);
let person2 = new Person("Mary", "woman", 17);
person1 和 person2 都有一个共同的 ==constructor== 属性, 且都是 Person
假如所有对象实例都有相同的属性或方法
function Person(name, sex, age) {
this.name = name;
this.sex = sex;
this.age = age;
this.career = "teacher";
this.skill = function(){console.log(("传道受业解惑")}
}
let person1 = new Person("Bob", "man", 18);
let person2 = new Person("Mary", "woman", 17);
这里 Bob 和 Mary 都具有相同的属性 career 和相同的方法 skill;
如果使用构造函数的方法则会造成内存的浪费。
JavaScript 中,每一个构造函数都有一个 prototype 属性,它指向另一个对象,这个对象的所有属性和方法都会没构造函数生成的实例所继承
function Person(name, sex, age) {
this.name = name;
this.sex = sex;
this.age = age;
}
Person.prototype.career = "teacher";
Person.prototype.skill = function(){console.log("传道受业解惑")};
let person1 = new Person("Bob", "man", 18);
let person2 = new Person("Mary", "woman", 17);
这里 person1 和 person2 都具有 career 属性和 skill 方法;
// 这个方法用来检测 prototype 和某个实例之间的关系
console.log(Person.prototype.isPrototypeOf(person1); // true
// 每个实力对象都有 hasOwnProperty() 方法, 用来判断某个属性属于自身还是属于 prototype
console.log(person1.hasOwnProperty("name")); // true
console.log(person1.hasOwnProperty("career")); // false
// in 运算符可以用来判断某个实例是否含有某个属性或方法,不管是自身的还是prototype的
console.log("name" in person1); // true
console.log("skill" in person1); // true
console.log('color' in person1); // false
in 运算符可以用来遍历某个对象的所有属性,即 for in 循环
bind 用法和 call 很类似,但是 bind 不会立即执行函数,而是返回一个绑定了 this 的新函数
const obj = {name: 'cym'}
function fn(age) {
console.log(this.name + '今年' + age + '岁了')
}
// 如上代码,我们要让 this 指向 obj
const bindFn = fn.bind(obj)
bindFn(24) // cym今年24岁了
根据上面的用法,我们不难 bind
的方法不仅可以绑定 this
还可以绑定参数,我们来简单实现一下
Function.prototype.bind2 = function(ctx = globalThis) {
// 取到我们要绑定的参数
const args = [...arguments].slice(1)
// 缓存 this,因为返回一个函数 this 就会变成新的函数
const that = this
// 返回一个函数
return function() {
// 返回函数里面的 arguments 是返回函数传入的参数哦,别搞混了
that.apply(ctx, args.concat([...arguments]))
}
}
bind
方法的实现其实蛮有意思的,因为 bind
方法返回一个函数,那么返回的这个函数如果被当做构造函数怎么办
const obj = {name: 'cym'}
function fn() {
console.log(this)
}
// 如上代码,我们要让 this 指向 obj
const bindFn = fn.bind(obj)
const instance = new bindFn(24) // fn {}
根据上面的代码返回结果来看,我们发现当绑定的函数作为构造函数来用的话,this
指向了原来的函数的实例,那么我们来实现一下完整的 bind
方法
Function.prototype.bind2 = function(ctx = globalThis) {
// 取得参数
const args = [...arguments].slice(1)
// 取得函数
const that = this
// 要返回一个函数,还要判断是否有进行实例化的操作
function Fn() {
const allArgs = args.concat([...arguments])
// 如果被实例化了
if (this instanceof Fn) {
that.apply(this, allArgs)
} else {
that.apply(ctx, allArgs)
}
}
// 但是我们需要保证原型不能丢失,还得是原来函数的实例
// 这种写法可能不雅观,因为直接让两个原型指向了同一个地址,一般情况下我们会使用一个临时性构造函数来处理一下
// Fn.prototype = this.prototype
Fn.prototype = Object.create(this.prototype)
// 返回这个绑定好 this 的函数
return Fn
}
来看下用法
const obj = {name: 'cym'}
function fn() {
console.log(this)
}
// 如上代码,我们要让 this 指向 obj
const bindFn = fn.bind2(obj)
const instance = new bindFn() // fn {}
bindFn() // {name: 'cym'}
今日所做:
1.看书半小时《刻意练习》
2.背单词100个。
3.深蹲50个。
4.打扫卫生。
5.投递简历大概150份。沟通人少于10人。
6.俯卧撑30个。
7.阅读文章五篇。
所列2020年3月2号。
多态通俗的讲就是一个接口多种实现方法,有时在程序设定之初,肯能会根据程序需求不同,不确定使用哪个函数实现,通过多天不需要修改源码,就可以实现
表现形式为 ==重写== 、 ==重载== 、 ==接口==
重写指子类重新定义父类方法。
function Person(name) {
this.name = name;
this.sayHello = function () {
console.log("Hello !!")
}
this.getName = function () {
console.log(this.name)
}
}
function Teacher(name) {
Person.apply(this, arguments);
this.sayHello = function () {
console.log("Hello, everyone. I am " + name + " !!")
}
}
let teacher = new Teacher("Lily");
console.log(teacher.sayHello()); // Hello, everyone. I am Lily !!
console.log(teacher.name); // Lily
console.log(teacher.getName()); // Lily
上边这段代码中,Teacher 继承了 Person 的 name 属性和 getName 方法,并且对 sayHello 方法进行了修改,即重写。
重载是指多个同名但参数不同的方法,在JS中,判断arguments的个数和类型,然后具体判断。
function foo1(a) {
console.log(a)
}
function foo2(a, b) {
console.log("a: " + a, "b: " + b)
}
function foo () {
if(arguments.length === 1) {
foo1.apply(null, arguments)
}
if(arguments.length === 2) {
foo2.apply(null, arguments)
}
}
foo(1); // 1
foo(1, 22); // a: 1 b: 22
将父对象的方法抛出异常,如果没有被实现就会报错
function Person() {
this.sayHello = function(){throw '没有定义该方法'}
};
function Teacher() {
this.sayHello = function(){
console.log("Hello everyone, I am a teacher.")
}
};
function Worker() {
this.sayHello = function(){
console.log("Hello, I am a worker.")
}
};
function Doctor(){};
Teacher.prototype = new Person();
Teacher.prototype.constructor = Teacher;
Worker.prototype = new Person();
Worker.prototype.constructor = Worker;
Doctor.prototype = new Person();
Doctor.prototype.constructor = Doctor;
let teacher = new Teacher();
console.log(teacher.sayHello()); // Hello everyone, I am a teacher.
let worker = new Worker();
console.log(worker.sayHello()); // Hello, I am a worker.
let doctor = new Doctor();
console.log(doctor.sayHello()); // error: Uncaught 没有定义该方法
结论: JS是无态的,或者说JS天生支持多态
↑↑↑ 接昨天
Blob 是指二级制大对象
参考文章
阮一峰:Javascript面向对象编程(二):构造函数的继承
阮一峰:Javascript面向对象编程(三):非构造函数的继承
假设有一个"动物"的构造函数 和 一个"猫"的构造函数
function Animal() {
this.species = "动物";
}
function Cat(name, breed) {
this.name = name;
this.breed = breed;
}
let cat1 = new Cat("咪咪", "加菲猫")
要求:使猫继承动物的属性和方法
将父对象的构造函数绑定在子对象上
function Cat(name,breed){
Animal.apply(this, arguments);
this.name = name;
this.breed = breed;
}
let cat1 = new Cat("咪咪", "加菲猫")
console.log(cat1.species); // 动物
将猫的prototype 对象指向 Animal 的实例,那么猫的实例就能继承 Animal 的属性和方法了。
Cat.prototype = new Animal();
console.log(cat1.species); // 动物
console.log(cat1.constructor); // Animal
这时 Cat 生成的 cat1 就会继承 Animal 的 species 属性,但是此时 cat1 的 constructor 属性也随之发生了改变,会导致继承链混乱,所以需要我们手动修改回来
Cat.prototype.constructor = Cat;
console.log(cat1.constructor); // Cat
==结论:如果替换了构造函数的 prototype 对象,那么必须要给新的 prototype 对象加上 constructor 属性, 并将这个属性指向原来的构造函数==
构造函数中所有不变的属性都可以直接写入 prototype 中,所以可以使 Cat 继承 Animal 的prototype。
// 改写Animal
function Animal() {}
Animal.prototype.species = "动物";
Cat.prototype = Animal.prototype;
Cat.prototype.constructor = Cat;
let cat1 = new Cat("咪咪", "加菲猫")
console.log(cat1.species); // 动物
==优点:效率高,不用建立 Animal 实例, 比较省内存==
==缺点:由于 Cat 和 Animal 的 prototype 属性指向同一个对象,所以修改Cat 的 prototype ,Animal 的 prototype 也会随之改变==
Cat.prototype.constructor = Cat;
console.log(Animal.constructor); // Cat
// 这段代码同时也会修改 Animal 的 constructor
此方法解决了上一种方法的缺点。
let Foo = function(){};
Foo.prototype = Animal.prototype;
Cat.prototype = new F();
at.prototype.constructor = Cat;
let cat1 = new Cat("咪咪", "加菲猫");
console.log(cat1.species); // 动物
console.log(Animal.constructor); // Animal
这种方法是将父对象的属性和方法拷贝进子对象实现继承
function Animal() {};
Animal.prototype.species = "动物";
function extend_1 (Child, Parent) {
let p = Parent.prototype;
let c = Child.prototype;
for (let i in p) {
c[i] = p[i]
}
}
extent_1(Cat, Animal);
let cat1 = new Cat("咪咪", "加菲猫");
console.log(cat1.species); // 动物
let Chinese = {
nation: '**'
};
let Foo = function(){};
Foo.prototype = Chinese;
let Doctor = new F();
Doctor.career = "医生";
仅适用于拷贝基本数据类型,引用数据类型只会获得一个引用地址,不会实现拷贝
可以实现引用数据类型的拷贝,比如对象和数组
2019年10月22日你要记录点什么?
参考文章:
MySQL 支持偶有标准SQL数值数据类型。
以下范围取值 前者是有符号的范围,后者是无符号的范围(unsigned)
TINYINT
SMALLINT
MEDIUMINT
INT/INTEGER
BIGINT
bind,call,apply都可以改变this的指向,且第一个参数都是this要指向的对象,即指定的上下文(上下文就是指调用函数的那个对象)
function checkDataType(obj){
if(Object.prototype.toString.call(obj) === '[object Array]') return "Array";
if(Object.prototype.toString.call(obj) === '[object Object]') return "Object";
if(Object.prototype.toString.call(obj) === '[object Function]') return "Function";
if(Object.prototype.toString.call(obj) === '[object String]') return "String";
if(Object.prototype.toString.call(obj) === '[object Number]') return "Number";
if(Object.prototype.toString.call(obj) === '[object Boolean]') return "Boolean";
if(Object.prototype.toString.call(obj) === '[object Symbol]') return "Symbol";
if(Object.prototype.toString.call(obj) === '[object Undefined]') return "Undefined";
if(Object.prototype.toString.call(obj) === '[object Date]') return "Date";
if(Object.prototype.toString.call(obj) === '[object Math]') return "Math";
if(Object.prototype.toString.call(obj) === '[object Set]') return "Set";
if(Object.prototype.toString.call(obj) === '[object Map]') return "Map";
}
git clone https://github.com/weblixin/learn_serve.git
cd learn_serve
npm i
key | value |
---|---|
规则方向 | 入方向 |
端口范围 | 3000/3000 |
授权对象 | 0.0.0.0/0 |
pm2 start bin/www -n learn
这样就能使用公网IP访问了
key | value |
---|---|
主机记录 | www |
记录值 | 公网IP |
访问配置好的域名就可以访问啦,这里配置的是www的
↑↑↑ 接昨天
参考文章
~
返回 2 的补码,~x
大致等同于 -(x+1)
~42 // -(42+1) ===> -43
在 -(x+1)
中唯一能够得到 0(或者严格来说时候 -0)的 x 值是 -1,也就是说 ~ 和一些数字在一起会返回一个假值 0,其他情况下则返回真值
-1 是一个 哨位值
,哨位值是那些在各个类型中被赋予了特殊含义的值。在 C 语言中 -1 代表函数执行失败,大于等于 0 的值代表函数执行成功
比如在 JavaScript 中字符串的 indexOf 方法也遵循这一惯例,该方法在字符串中搜索指定的字符串,如果找到就返回该子字符串所在的位置,否则返回 -1
我们知道在 JavaScript 中假值有:undefined、null、false、+0、-0、NaN、''
,其他都为真值,所以负数也是真值,那么我们就可以拿着 ~
和 indexOf
一起检结果强制类型转换为 真/假 值
const str = 'hello world'
~str.indexOf('lo') // -4,真值
if (~str.indexOf('lo')) {
// true
// 找到匹配
}
~str.indexOf('ol') // 0,假值
!~str.indexOf('ol') // true
if (!~str.indexOf('ol')) {
// true
// 没有找到匹配
}
~ 要比 >=0
和 == -1
更简洁
我们经常使用 ~~
来截取数字值的小数部分,以为这是和 Math.floor 效果是一样的,实际上并非如此
~~
中第一个 ~ 执行 ToInt32 并反转字位,然后第二个在进行一次字位反转,就是将所有的字位反转回原值,最后得到的结果仍是 ToInt32 的结果
~~
只适用于 32 位的数字,更重要的是他对负数的处理与 Math.floor 不同,所以使用时要多加注意
Math.floor(1.9) // 1
~~1.9 // 1
// 操作负数
Math.floor(-1.9) // -2
~~-1.9 // -1
~~x
能将值截除为一个 32 位的整数,x | 0
也可以,而且看起来更简洁哦,不过出于对运算符优先级的考虑,我们更倾向于使用 ~~x
~~1.9 // 1
1.9 | 0 // 1
~~-1.9 // -1
;-1.9 | 0 // -1
需求: 将下边的数据根据 name
字段的 -
转成 element-ui
树形控件需要的格式,最后一级数据添加 id
和 disabled
字段,所有层级都有 label
字段
const data = {code: 200, data: [{"id":1,"name":"地球","status":1},{"id":2,"name":"埃及-金字塔","status":0},{"id":3,"name":"美国-洛杉矶-女神像","status":1},{"id":4,"name":"**-河北-唐山-路北区","status":0}]}
// 取数据
let {data: arr} = data;
// 取出name, 转成数组
let nameArr = arr.map(item => item.name.split("-"))
// 将name的数组转换为需要的格式
let cc = nameArr.map(item => mapArrToObj(item))
// 合并相同name的数组
let dd = composeRepeatItem(cc)
// 将其他字段添加到数据当中
let eee = appendOtherKeys(arr, dd)
console.log(eee, "eee")
// 将数组转化为树状对象格式
function mapArrToObj(arr) {
let obj = {}, i= 0;
obj.label = arr[i];
i++;
if(i < arr.length) {
loopChild(obj, arr, i)
}
return obj
}
// 判断对象中是否存在children,不存在则添加
function loopChild(obj ,arr, i) {
if (!obj.children) {
obj.children = [{label:arr[i]}];
i++;
if(i < arr.length) {
loopChild(obj.children[0], arr, i)
}
}
}
// 合并相同label的数组
function composeRepeatItem(arr) {
let newArr1 = [], o = [], s = [];
for (var i = 0; i < arr.length; i++) {
let item = arr[i];
if(newArr1.indexOf(item.label) === -1) {
newArr1.push(item.label)
o.push(item)
}
}
for (var m = 0; m < arr.length; m++) {
let arr_item = arr[m];
for (var n = 0; n < o.length; n++) {
let o_item = o[n]
if(arr_item.label === o_item.label) {
if(o_item.children) {
o_item.children.push(arr_item.children[0])
}
}
}
}
for (var k = 0; k < o.length; k++) {
o[k].children && o[k].children.splice(0, 1);
let o_item1 = o[i];
if(o[k].children) {
o[k].children = composeRepeatItem(o[k].children)
}
s.push(o[k])
}
return s
}
// 将其他字段添加到数组中
function appendOtherKeys(arr, newArr) {
for (var i = 0; i < arr.length; i++) {
let arr_item = arr[i];
let names = arr_item.name.split("-");
for (var l = 0; l < newArr.length; l++) {
let new_arr_item = newArr[l];
let index = 0;
if(new_arr_item.label === names[index]) {
loopToAppend(new_arr_item, names, index, arr_item)
}
}
}
return newArr
}
// 判断是否有children,有则继续执行函数,没有则添加字段
function loopToAppend(obj, names, index, arr_item) {
if(obj.children) {
index ++;
for (var i = 0; i < obj.children.length; i++) {
if(obj.children[i].label === names[index]) {
loopToAppend(obj.children[i], names, index, arr_item)
}
}
} else if(!obj.children) {
obj.id = arr_item.id
obj.disabled = arr_item.status !== 1
}
}
总结: 以上代码还有待优化,性能较差
pcre
和 openssl
依赖yum -y install pcre* yum -y install openssl*
nginx
压缩包wget http://nginx.org/download/nginx-1.16.1.tar.gz
nginx
压缩包tar -zcvf nginx-1.16.1.tar.gz
nginx-1.16.1
文件夹,执行配置文件,编译,安装依赖cd nginx-1.16.1
./configure
make -j4
make install
ln -s /usr/local/nginx nginx-1.16.1
cd /usr/local/nginx/conf
nginx -t
nginx
vim /etc/profile
PATH=$PATH:/usr/local/nginx/sbin
export PATH
source /etc/profile
nginx
之前一直听到装饰器这个词, 一直觉得是什么高深的东西, 这次打算尝试学习一下.
开始学习之前, 需要准备一下怎么让写的代码直接能运行起来, 一种方式在是babel官网提供的 try it out; 另一种就是本地配置babel的方式, 我选择本地编译
安装babel以及需要支持装饰器(Decorator)的插件
npm init
npm install --save-dev @babel/core @babel/cli
npm install --save-dev @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties
{
"plugins": [
["@babel/plugin-proposal-decorators", {
"legacy": true
}],
["@babel/plugin-proposal-class-properties", {
"loose": true
}]
]
}
下面就可以编译指定的文件了
babel decorator.js --out-file decorator-dist.js
简单来说, 装饰器是一个函数, 他的用法比较特殊。写成 @ + 函数名
的方式,放在类和方法的前面,用来对类和类方法进行注释或者修改
先来一段代码简单的认识一下:
@addProperty
class Person {}
function addProperty(target) {
target.age = 18;
}
console.log(Person.age) // 18
这段代码@addProperty
就是一个装饰器, 给类Person
添加了一个静态属性age
。打印装饰器的参数target
,可以发现它就是Person
这个类本身
后续继续更新ing....
因为最近有一个新项目比较急,而且是前后端不分离的,对我说还是比较难得。首先,接触了java模板:Thymeleaf,语法类似与vue的模板语法。这类模板语法主要使用[[${}]]这类标记。其他的与vue模板语法上没有太大的差异。可以使用switch,text,if之类的判断。但是这个语法的<script th:inline="javascript">一定要这样写。
2019年10月23日你要记录点什么?
2019年10月21日你要记录点什么?
这个概念一直都只有听说过,但是并不太理解到底是怎么一回事,今天就让咱们来学一学吧
var curry = (fn,...args) => {
var func = args.length<fn.length?
(...arguments) => curry(fn,...args,...arguments):
fn(...args);
return func;
}
function sumFn(a,b,c) {return a+b+c;}
var sum = curry(sumFn)
console.log(sum(2)(3)(5))
生活很有意思,意识到钱的重要性,但不可为之奴隶,可由不得自己,尽量去做到不为财务而苦恼吧!
单词 30个 语法呢我老师病了 就停了 朗读课文两篇。春节计划就是看书,写码,看视频。加油!
Promise
添加 Promise.map
方法有时候需要在一列 Promise
中迭代,并对所有的 Promise
都执行某个任务,非常类似于数组可以做的那样(比如 forEach、map 等),如果这些任务是同步的那这些任务就可以做,但是从根本上上来说 Promise
任务是异步的,所以我们需要一个类似的工具方法
// Promise.map 的实现
if (!Promise.map) {
Promise.map = function(vals, cb) {
return Promise.all(
vals.map(val => {
return new Promise((resolve, reject) => {
cb(val, resolve, reject)
})
})
)
}
}
// 测试
const p1 = Promise.resolve(21)
const p2 = 42
// const p3 = Promise.reject('failed')
Promise.map([p1, p2], function(val, done, failed) {
// 保证 val 是 Promise,统一格式
Promise.resolve(val).then(res => {
done(res * 2)
// 捕获失败的情况
}, failed)
}).then(result => {
console.log(result, 'result')
}).catch(error => {
console.log(error, 'error')
})
// 最终输出结果是,如果加上一个失败的 promise 该函数也是可以捕获的哦
// [42, 84]
1.面试失败
2.和好友沟通面试环节。
3.查找面试答案。
4.深蹲50个。俯卧撑10个。
5.单词76个,阅读文章5篇。
6.面试总结。
学习过JavaScript的童鞋们都知道,在javascript中有一个特殊的对象,称为全局对象(Global Object),它及其所有属性都可以在程序的任何地方访问,即全局变量。小编在node面前完全是小白,那么在最近学习node.js中,全局变量当然是必须也要学。按照 ECMAScript 的定义,满足以下条 件的变量是全局变量:
*** 在最外层定义的变量;
function (exports, require, module, __filename, __dirname) {
// var a = 1;
// console.log(arguments.length);
// console.log(arguments.callee + "");
}
实际上模块中的代码都是包装在一个函数中执行,在函数中的都是局部的变量,并且在函数执行的同时传了5个实参。
1,Exports:该对象用来将变量或者函数暴露到外部
2,Require:函数,用来引入外部的模块
3, Module:module代表的是当前模块本身,实际上exports就是module的属; 当你console.log(module.exports == exports); 输出为:true
4,__filename:当前模块完整的路径
,5,__dirname:当前模块文件夹的完整路径
背单词 30个 学习新知识点 so that句型 和in order to在句首和句中的区别 on time 和in time的使用方式。
/usr/local/src
wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.26-linux-glibc2.12-x86_64.tar.gz
tar -zxvf mysql-5.7.26-linux-glibc2.12-x86_64.tar.gz
/usr/local/mysql-5.7.26
mv mysql-5.7.26-linux-glibc2.12-x86_64 /usr/local
cd ../
mv mysql-5.7.26-linux-glibc2.12-x86_64 mysql-5.7.26
groupadd mysql
useradd -r -g mysql mysql
cd /
mkdir -p data
cd data/
mkdir -p mysql
chown mysql:mysql -R /data/mysql
vim /etc/my.cnf
[mysqld]
bind-address=0.0.0.0
port=3306
user=mysql
basedir=/usr/local/mysql-5.7.26
datadir=/data/mysql
socket=/tmp/mysql.sock
log-error=/data/mysql/mysql.err
pid-file=/data/mysql/mysql.pid
#character config
character_set_server=utf8mb4
symbolic-links=0
cd /usr/local/mysql-5.7.26/bin/
./mysqld --defaults-file=/etc/my.cnf --basedir=/usr/local/mysql-5.7.26/ --datadir=/data/mysql/ --user=mysql --initialize
cp ./support-files/mysql.server /etc/init.d/mysqld
chown 777 /etc/my.cnf
chmod +x /etc/init.d/mysqld
vim /data/mysql/mysql.err
root@localhost:
后边的就是密码
service mysqld start
cd /usr/local/mysql-5.7.26/bin
./mysql -u root -p
回车,输入密码
mysql> set password=password('admin');
mysql > quit
service mysqld stop
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.