本周学习总结
字符串中用的少的一些方法
console.log('z'.charCodeAt(0));// 122
console.log(String.fromCharCode(122));// 'z'
实现一个push方法
Array.prototype.push=function (val) {
this[this.length]=val;
return this.length
};
一道有趣的题
某公司1到12月份的销售额 例如 let obj = { 1: 222, 2: 123, 5: 888 }; 数据处理为 [ 222, 123, null, null, 888, null, null, null, null, null, null, null ] let keys = Object.keys(obj); // 第一种方法 let arr = []; for (let i = 1; i < 13; i++) { if (~keys.indexOf(`${i}`)) { arr[i - 1] = obj[i]; } else { arr[i - 1] = null; } } // 第二种方法 let arr1 = Array.from({length: 12}, (val, i) => { if (~keys.indexOf(`${i + 1}`)) { return obj[i + 1] } return null });
重构
源代码
let checkType=function(str, type) {
switch (type) {
case 'email':
return /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(str);
case 'mobile':
return /^1[3|4|5|7|8][0-9]{9}$/.test(str);
case 'tel':
return /^(0\d{2,3}-\d{7,8})(-\d{1,4})?$/.test(str);
case 'number':
return /^[0-9]$/.test(str);
default:
return true;
}
}
修改
let checkType=(function(){
let rules={
email(str){
return /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(str);
},
mobile(str){
return /^1[3|4|5|7|8][0-9]{9}$/.test(str);
},
tel(str){
return /^(0\d{2,3}-\d{7,8})(-\d{1,4})?$/.test(str);
},
number(str){
return /^[0-9]+$/.test(str);
},
};
//暴露接口
return function (str,type){
//如果type是函数,就扩展rules,否则就是验证数据
if(type.constructor===Function){
rules[str]=type;
}
else{
return rules[type]?rules[type](str):false;
}
}
})();
console.log(checkType('188170239','mobile'));
checkType('money',function (str) {
return /^[0-9]+(.[0-9]{2})?$/.test(str)
});
//使用金额校验规则
console.log(checkType('18.36','money'));
函数输出
payChannelEn2Cn(tag){
let _obj = {
'cash': '现金',
'wx_pay': '微信支付',
'bank_trans': '银行转账',
'pre_pay': '预付款'
};
return _obj[tag];
}
重构就是一个逐步的过程,一次次的小改动,逐步形成一个质变的过程,才能形成一个质边的过程
设计模式
工厂模式
class Product{ constructor(name) { this.name=name; } init(){ console.log('init'); } fun(){ console.log('func'); } } class Factory { create(name) { return new Product(name); } } let factory = new Factory(); let p = factory.create('李四'); p.init();//init p.fun();// func
遇到new的时候就应该考虑是否用工厂模式
优点
- 创建对象的过程可能很复杂,但我们只需要关心创建的结果
- 构造函数和创建者分离,符合"开闭原则"
- 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以了
应用
它根据传入参数的不同创建元素或者去寻找上下文中的元素,创建成相应的jQuery对象 class jQuery { constructor(selector) { super(selector) } add() { } // 此处省略若干API } window.$ = function(selector) { return new jQuery(selector) }
Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。 Vue.component('async-example', function (resolve, reject) { setTimeout(function () { // 向 `resolve` 回调传递组件定义 resolve({ template: '<div>I am async!</div>' }) }, 1000) })
元素默认蓝色边框
input
标签元素(如button
、text
、areatext
)的一些事件(如click
、focus
等),在很多浏览器下默认会有蓝色边框出现outline:none; outline-width:0;
opacity
会让所有子元素都变透明,别使用,改成
rgba
div内置img元素,底部总有间距
img 设置
display:block
,使其变成块级元素
<div class="nnn">
<img src="../assets/3.jpg" alt="">
</div>
.nnn {
width: 400px;
height: 300px;
display: inline-block;
border: 2px solid #ccc;
img {
width: 400px;
height: 300px;
display: block;
}
}
元素自动填充上背景色
input:-webkit-autofill{
box-shadow: 0 0 0px 1000px white inset !important;
}
select:-webkit-autofill{
box-shadow: 0 0 0px 1000px white inset !important;
}
textarea:-webkit-autofill{
box-shadow: 0 0 0px 1000px white inset !important;
}
transform 基数值导致字体模糊
不要给transform属性值设置奇数和小数值
调整整体元素高度不要为基数
:last-child和:last-of-type
:last-child
选取一群兄弟元素中的最后一个元素,且最后的这个元素必须是所生命的指定元素(注意2个条件)
:last-of-type
选取一群兄弟元素中的最后一个指定类型的元素同理使用与
:th-last-child(n)
和:nth-last-of-type(n)
:last-of-type
更严谨一些
内存泄露及如何避免
未声明的变量
function fn () {
a = "Actually, I'm a global variable"
}
function fn () {
window.a = "Actually, I'm a global variable"
}
这个可以直接避免,因为我从来不会这么写
使用this创建的变量
function fn () {
this.a = "Actually, I'm a global variable"
}
fn();
避免此情况的解决办法是在 JavaScript 文件头部或者函数的顶部加上 'use strict'
定时器引起的内存泄露
vue使用了定时器,需要在beforeDestroy 中做对应销毁处理
如果在mounted/created 钩子中使用了$on,需要在beforeDestroy 中做对应解绑($off)处理
$on 是监听作用,离开的时候要清除
记住使用定时器一定要清除定时器
instanceof
instanceof 是用来判断A是否为B的实例,如果A是B的实例,则返回true,否则返回false
instanceof 三大弊端:
对于基本数据类型来说,字面量方式创建出来的结果和实例方式创建的是有一定的区别的
console.log(1 instanceof Number)//false console.log(new Number(1) instanceof Number)//true 从严格意义上来讲,只有实例创建出来的结果才是标准的对象数据类型值,也是标准的 Number 这个类的一个实例;对于字面量方式创建出来的结果是基本的数据类型值,不是严谨的实例
typescript
函数
**返回值**
const fn = (): number => 1;
const obj = {
fn(): string {
return '1';
}
};
**函数类型**
type FnType = (x: number, y: number) => string;
const add: FnType = (x, y) => (x + y).toString();
console.log(add(1, 100)); // '3'
in关键词
in 也是一个 类型关键词, 可以对联合类型进行遍历
type Person = { name: number, age: number }; const add = (obj: Person) => obj.name + obj.age; console.log(add({name: 1, age: 2})); type Person1 = { [item in 'name' | 'age']: number } const add1 = (obj: Person1) => obj.name + obj.age; console.log(add1({name: 1, age: 2}));
[]操作符
使用
[]
操作符可以进行索引访问,也是一个 类型关键词interface Person { name: string age: number } type x = Person['name'] // x is string
剩余参数
const buildName = (firstName: string, ...restName: any[]) =>
firstName + '' + restName.join('');
console.log(buildName('s', 1, 2, 3, 4, 5, 's'));
// s12345s
闭包有趣特性
function getGetNext() {
let i = 2;
return function getNext() {
const next = i;
i = i * 2;
return next;
}
}
let a=getGetNext();
console.log(a()); // 2
console.log(a()); // 4
console.log(a()); // 8
let b=getGetNext();
console.log(b());// 2
箭头函数的注意事项
this的确定
- 和普通函数不同,箭头函数的this就是定义时的所在的对象,而不是使用时所在的对象。也就是说一旦定义的箭头函数,this对象就是定义时所在的对象
不可以当做构造函数
也可以说不能new一个箭头函数
不可以使用arguments,可以用...代替
不可以使用yield命令
Generator
function* add(i = 42) {
while (i < 48) {
yield i++
}
}
for (let item of add()) {
console.log(item);
}
42
43
44
45
46
47
决定自己的高度的是你的态度,而不是你的才能
记得我们是终身初学者和学习者
总有一天我也能成为大佬