分类
ES6

JavaScript 中你应该知道的 旧习惯 与 新习惯(二)

创建对象时使用可计算属性名

旧习惯

  • 之前,如果属性名是个变量或者需要动态计算,则只能通过 对象.[变量名] 的方式去访问,且只能运行时才能确定
var name = 'answer';   
var obj = { };
obj[name]=42;
console.log(obj[name]) // 42

新习惯

var name = 'answer';   
var obj = { 
[name]:42
};
console.log(obj[name]) // 42

同名变量初始化对象时,使用简写语法

旧习惯:哪怕变量是局部变量,也要写完整key与value

function getParams(){
	let name;
	// 其他操作
	return {name:name}
}

新习惯:使用简写

function getParams(){
	let name;
	// 其他操作
	return {name}
}

使用 *Object.assign()*代替自定义的扩展方法或者显式复制所有属性

旧习惯 使用遍历key然后复制给新的对象

function mergeObjects() {
    var resObj = {};
    for(var i=0; i < arguments.length; i += 1) {
         var obj = arguments[i],
             keys = Object.keys(obj);
         for(var j=0; j < keys.length; j += 1) {
             resObj[keys[j]] = obj[keys[j]];
         }
    }
    return resObj;
}

新习惯 使用Object.assign代替

const target = { a: 1, b: 2 };

const returnedTarget = Object.assign({}, source);

console.log(returnedTarget); // {a:1,b:2}

使用属性扩展语法

旧习惯 基于已有对象创建新对象时,使用 Object.assign

const target = { a: 1, b: 2 };
const source = { b: 3, c: 4 };

const returnedTarget = Object.assign({},target, source);

console.log(returnedTarget); // {a:1,b:3,c:4}

新习惯 使用属性扩展语法

const a = { a: 1, b: 2 };
const b = { b: 3, c: 4 };

const returnedTarget = {...a,...b}; // {a: 1, b: 3, c: 4}

使用 Symbol 避免属性名冲突

旧习惯 使用可读性很差的又很长的字符串来用作属性名来避免冲突

const shapeType = {
  triangle: 'Triangle'
};

function getArea(shape, options) {
  let area = 0;
  switch (shape) {
    case shapeType.triangle:
      area = .5 * options.width * options.height;
      break;
  }
  return area;
}

getArea(shapeType.triangle, { width: 100, height: 100 });

新习惯

const shapeType = {
  triangle: Symbol()
};

function getArea(shape, options) {
  let area = 0;
  switch (shape) {
    case shapeType.triangle:
      area = .5 * options.width * options.height;
      break;
  }
  return area;
}

getArea(shapeType.triangle, { width: 100, height: 100 });

使用 Object.getPrototypeOf/setPrototypeOf 来代替 Proto

旧习惯 使用非标准的 Proto 来获取或者设置原型

新习惯 使用标准方法 Object.getPrototypeOf/setPrototypeOf 来获取或者设置原型

具体查看 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/proto

使用对象方法的简写语法来定义对象中的方法

旧习惯 key 与 value 的形式

const obj = {
    fun : function(){
        // ...
    }
}

新习惯

const obj = {
    fun(){
        // ...
    }
}

遍历的姿势-可迭代对象

旧习惯 使用for循环或者 forEach 方法 来循环

// for
for(let i = 0; i < array.length; ++i){
    console.log(array[i]);
}
// forEach
array.forEach(entry => console.log(entry));

新习惯 当不需要下标的时候,考虑for-of

let arr = [1, 2, 3, 4]
for(let item of arr) {
  console.log(item) // 1, 2, 3, 4 
}

需要下标可以考虑
let arr = [1, 2, 3, 4]
for(let [index, value] of arr.entries()) {
  arr[index] = value * 10
}
console.log(arr) // [ 10, 20, 30, 40 ]

遍历的姿势-DOM

旧习惯 为了遍历DOM集合,将DOM集合转为数组或者使用Array.prototype.forEach.call 方法

Array.prototype.slice.call(document.querySelectorAll("div")).forEach(
    (div)=>//....
)
    
Array.prototype.forEach.call(document.querySelectorAll("div"),div=>{
    // ...
})

新习惯 确保DOM集合是可迭代的,然后使用for-of

for(const div of document.querySelectorAll("div"){
    // ...
}

在使用 Function.prototype.apply() 的大部分场景就可以使用可迭代对象的展开语法

旧习惯

const numbers = [5, 6, 2, 3, 7];

const max = Math.max.apply(null, numbers);

console.log(max);
// expected output: 7

const min = Math.min.apply(null, numbers);

console.log(min);
// expected output: 2

新习惯 使用可迭代对象的展开语法

const numbers = [5, 6, 2, 3, 7];

const max = Math.max([...numbers]);

console.log(max);
// expected output: 7

const min = Math.min([...numbers]);

console.log(min);
// expected output: 2

该用解构用解构

旧习惯 使用对象中的少量属性就把整个对象保存

const bird = getBird();
console.log(bird.age);
console.log(bird.name);

新习惯 使用解构赋值,不需要整个对象的时候

let {age,name} = getBird();
console.log(age);
console.log(name);

对可选项使用解构赋值

旧习惯 使用代码处理默认值

function check(options){
    let options = Object.assign({},options,{
        a:1,
        b:2,
    })
    if(options.c === undefined){
        options.c = options.a + options.b
    }
    console.log(options.c)
    // ...
}

新习惯 将默认值提出来,通过解构来直接处理

function check(
{	
    a=1,
    b=2,
    c=a+b
} = {}){
    console.log(c)
    // ...
}

check({a:2}) // 4
分类
前端开发环境 技术

基于docker 搭建Verdaccio的教程

其实按照网上的教程基本都能成功启动,为了方便下次查找我在整理下

docker pull verdaccio/verdaccio

首先

docker run -it --rm --name verdaccio -p 4873:4873 verdaccio/verdaccio

这样就可以运行了,但是这样文件和更改不能持久化,一重启动就没了,肯定不是我们想要的效果

 -v /home/verdaccio/storage:/verdaccio/storage
 -v /home/verdaccio/config:/verdaccio/conf
 -v /home/verdaccio/plugins:/verdaccio/plugins

这样就可以了。

然后你兴高采烈的一敲命令,报错了。

这个由于启动时容器会去找 /home/verdaccio/config/config.yaml 文件,所以在 config 文件夹新建该文件,填入以下内容:

storage: /verdaccio/storage
auth:
  htpasswd:
    file: /verdaccio/conf/htpasswd
uplinks:
  npmjs:
    url: https://registry.npm.taobao.org/
packages:
  '@*/*':
    access: $all
    publish: $authenticated
    proxy: npmjs
  '**':
    proxy: npmjs
logs:
  - {type: stdout, format: pretty, level: http}
  • htpasswd 文件是用来存储 npm 用户及密码信息的文件
  • uplinks 上游源改为了淘宝的镜像源,这样在下载找不到的包的时候就会从淘宝下载。
  • 需要注意的是,上面配置文件的路径都是针对 docker 容器内部来说的。

这样打开你本地的 4873 就可以访问了,更多的设置建议看官方文档

参考链接

https://verdaccio.org/docs/zh-CN/next/docker

分类
ionic 前端开发环境 技术

ionic 编译的环境变量配置

No installed build tools found. Install the Android build tools version

有时候,新电脑编译apk的时候会报这些错,这其实都是环境变量没配置好导致的

首先先找到自己的sdk安装位置

打开环境变量配置

%ANDROID_HOME%\platform-tools

%ANDROID_HOME%\tools

修改完终端记得关闭下软件再重新打开才可以生效,当然直接重启电脑也是没问题的

分类
前端开发环境 技术

npm i 报错

一般在别人电脑跑的好好的,自己安装不起来的试试这套操作

npm cache verify 验证缓存

npm cache clean -f 强制清除缓存

这套结束后 npm i 之后 就好了

参考: https://docs.npmjs.com/cli/cache.html

分类
angular 技术

记一次写TS时,遇到的坑

当有时候想要创建一个 [[],[],[]]的时候,你会用什么方式尼?

[...Array(3)].fill([]);

[...Array(3)].map(i=>[]);

亦或者会想到

Array(3).fill(0).map(i=>[])

来给大家比较下这三个的区别

[...Array(3)].fill([]);

有坑,相信不少人也遇到过,具体的表现 可以看一下这段代码

var b = [...Array(3)].fill([]);
b[0].push('qiupu'); 
console.log(b);
// 0: ["qiupu"]
// 1: ["qiupu"]
// 2: ["qiupu"]

这个就不再多解释了,看不懂的可以加下群768901972

[...Array(3)].map(i=>[]);

在JS里写的时候是没有问题的,

var a = [...Array(3)].map(i=>[]); 
a[0].push('qiupu');
console.log(a);
// 0: ["qiupu"]
// 1: []
// 2: []

Array(3).fill(0).map(i=>[])

这个看着和上面那个没什么区别,就多了一次fill(0),那他的意义是什么,就是先填充0,避免了 TS 在转译目标为ES5的 将他编译为 Array(20).slice().map(function (i) { return []; })

这篇文章主要是告诉大家,目前的TS的转译可能还存在一定的问题,使用的时候,应该注意下,特别是空值的处理之类的,希望能帮到你

提供一个在线测试工具,方便没有TS环境

分类
技术

学习清单(2019)

2019年只剩4个月了,列一些准备实现的事情

1.webpack4 的配置与使用(1年内)

2.搭建一个自己的开发脚手架(半年内)

3.参照ng的脏检查,自己实现一个脏检查(1年内)

4.这周的代码要比上周多点变化(每周)

5.gitlab的自动化部署(1年内)6.通过软考(就这一次)

7.至少发一篇技术点的文章(每月)

8.看至少2篇掘金的新趋势(每天)

分类
ES6

从一道平平无奇的题开始认识 set,sort等功能

拿到题第一步,读懂题目 要求 数组扁平化 去重 升序排列 数组

输入参数是一个[[]]的形式,第一步扁平

function flatten(arr) {
     while (arr.some(item => Array.isArray(item))) {
         arr = [].concat(...arr);
     }
     return arr;
 }

这些都很基础, … 与 some ,不明白的随便看看es6 就明白了

 arr =  [...new Set(flatten(arr))];  //去重 转为set 去重,再转为数组
 function sortNumber(a,b)
 {
 return a - b
 }
arr.sort(sortNumber)

这一步的sortNumber 是个函数 有a,b两个输入,当输出的值 小于 0 ,那么 a 会被排列到 b 之前; 反之b 会被排列到 ba之前 .

有什么不明白的留言就可以,随缘回复

分类
angular 小技巧

base64 转为blob 触发下载

/**
   * base64转为blob然后触发下载
   */
  base64toBlob(base64: string, filename: string, contentType = 'application/msword') {
    const url = `data:${contentType};base64,${base64}`;
    // console.log(url);
    fetch(url).then(res => res.blob())
      .then(blob => {
        const aTag = document.createElement('a');
        aTag.download = filename;
        aTag.href = URL.createObjectURL(blob);
        aTag.click();
        // 调用此方法,让浏览器知道不再保留对文件的引用。
        URL.revokeObjectURL(aTag.href);
      });
  }
分类
git 前端开发环境 小技巧

git 合并的时候报错

fatal: refusing to merge unrelated histories

有时候会新项目合并的时候会报这个错误,原因其实很简单,就是代码可能是直接从老项目整个拖过来的,导致了

git认为是写错了 origin ,如果开发者确定是这个 origin 就可以使用 --allow-unrelated-histories 告诉 git 自己确定

git pull –allow-unrelated-histories 就可以

分类
前端开发环境 小技巧

canvas 中的使用小技巧

长期更新

canvas画布的大小不是由样式决定的,请不要使用样式来确定画布大小,正确的确定画布的大小是 这样的

<!-- 样式改的是缩放大小,要这样写 -->
  <canvas #canvas1 width="1024" height="682"></canvas>

想了解更多可以看这篇
https://blog.csdn.net/cherrybomb1111/article/details/68951407