javacripit 常用的代码片段 + SnippetsLab 使用

473 阅读4分钟

前言

一个优秀的开发工程师,不应该重复的造轮子,而是应该在学习工作中,抽取和积累常用且经典的代码,保存为代码片段,有需要时随手翻出,节省重复码代码的时间来学习新知识,新业务,进行提高,这种工作坚持时间越长,效果越显著,良性的循环才会产生更大的惊喜,下面介绍一下一款代码片段的管理工具snippestlab。

image.png

我们日常JavaScript中的一些常用代码片段

1. makeMap

检测某值是否在字符串(逗号分隔的字符串)中存在, 运用了柯里化函数和缓存函数

/**
 * Make a map and return a function for checking if a key
 * is in that map.
 * map 对象中的[name1,name2,name3,name4]  变成这样的map{name1:true,name2:true,name3:true,name4:true}
 * 并且传进一个key值取值,这里用到策略者模式
 * expectsLowerCase 是否开启小写转换
 */
function makeMap(str, expectsLowerCase) {
	var map = Object.create(null); //创建一个新的对象
	var list = str.split(","); //按字符串,分割
	for (var i = 0; i < list.length; i++) {
		map[list[i]] = true; //map 对象中的[name1,name2,name3,name4]  变成这样的map{name1:true,name2:true,name3:true,name4:true}
	}
	return expectsLowerCase
		? function (val) {
				return map[val.toLowerCase()];
		  } //返回一个柯里化函数 toLowerCase转换成小写
		: function (val) {
				return map[val];
		  }; //返回一个柯里化函数 并且把map中添加一个 属性建
}

不开启小写转换使用

var isBuiltInTag = makeMap("slot,component", true);

console.log(isBuiltInTag("SlOt")); // true 找不到的返回undefined

开启小写转换使用

var isBuiltInTag = makeMap("slot,component", false);

console.log(isBuiltInTag("SlOt")); // undefined 

2. remove

删除数组中某一项, 该函数运用了indexOf,不可使用下标删除

/**
  * Remove an item from an array
  *    //删除数组
  */
function remove(arr, item) {
    if (arr.length) {
      var index = arr.indexOf(item);
      if (index > -1) {
        return arr.splice(index, 1);
      }
    }
}
let arr = [{name:"张三"},{name:"李四"}]; 
let item = arr[1]; 
remove(arr, item) // 删除数组 arr 的第二项数据 | 返回值是删除的数据

3. hasOwn

检查是否为自身属性,会忽略原型链继承的属性

/**
  * Check whether the object has the property.
  * 检查对象属性是否是实例化还是原型上面的 
  * 该方法会忽略掉那些从原型链上继承到的属性,只有obj对象自身的属性才会返回true
  */
var hasOwnProperty = Object.prototype.hasOwnProperty;

function hasOwn(obj, key) {
    return hasOwnProperty.call(obj, key);
}
let obj = { 
    name: "张三"
}
hasOwn(obj,'name') // true
hasOwn(obj,'__proto__') // false

4. cached

缓存函数,利用对象对字符串进行缓存

/**
 * 缓存函数,利用对象对字符串进行缓存
 * @param {*} fn 
 * @returns 
 */
function cached(fn) {
	var cache = Object.create(null);
	return function cachedFn(str) {
		var hit = cache[str];
		return hit || (cache[str] = fn(str));
	};
}
  1. 字符串转换成驼峰使用
/**
* 将连字符(-)分隔的字符串转换成驼峰写法
* 如: v-model 变成 vModel
*/
var camelizeRE = /-(\w)/g;
let camelize = cached(function (str) {
  console.log(11);
	return str.replace(camelizeRE, function (_, c) {
		return c ? c.toUpperCase() : "";
	});
});

console.log(camelize('user-name'));
console.log(camelize('user-name'));

输出

11 // 只会调用一次
userName
userName
  1. 首字母大写使用
**
 * 将首字母大写
 */
var capitalize = cached(function (str) {
	return str.charAt(0).toUpperCase() + str.slice(1);
});

console.log(capitalize('user')); // User
  1. 驼峰转连字符使用
// \B的用法: \B是非单词分界符,即可以查出是否包含某个字,如“ABCD”中是否包含“BCD”这个字。
var hyphenateRE = /\B([A-Z])/g;
var hyphenate = cached(function (str) {
  //大写字母,加完减号又转成小写了 比如把驼峰 aBc 变成了 a-bc
  //匹配大写字母并且两面不是空白的 替换成 '-' + '字母' 在全部转换成小写
  return str.replace(hyphenateRE, "-$1").toLowerCase();
});

console.log(hyphenate('aBchFa')); // a-bch-fa

5. 改变this指向

/* istanbul ignore next */
//绑定事件 并且改变上下文指向
function polyfillBind(fn, ctx) {
    function boundFn(a) {
      var l = arguments.length;
      // 1. 无参数直接调用 .call
      // 2. 一个参数传参调用 .call
      // 3. 其余参数 fn.apply(ctx, arguments)
      return l? l > 1? fn.apply(ctx, arguments): fn.call(ctx, a): fn.call(ctx);
    }
    boundFn._length = fn.length;
    return boundFn;
}

//执行方式
function nativeBind(fn, ctx) {
    return fn.bind(ctx);
}

//bing 改变this上下文
var bind = Function.prototype.bind ? nativeBind : polyfillBind;
let o = {
    a: 10,
    fn: function() {
      console.log(a);
    }
}

a = 20;
console.log(bind(o.fn, o)()); // 不传参 a: 10 

console.log(bind(o.fn, this)()); // 不传参 a: 20
let o = {
	a: 10,
	fn: function (a) {
		console.log(a, this.a);
	},
};
console.log(bind(o.fn, this)(30)); // 传参 a: 30 undefined(Node环境) | 20(Window)

console.log(bind(o.fn, this)(30)); // 传参 a: 30 10

6. toArray

从数组第几位开始截取,返回新数组

/**
 * 将假的数组转换成真的数组
 * 主要用于参数截取
 */
function toArray(list, start) {
	start = start || 0;
	var i = list.length - start;
	var ret = new Array(i);
	while (i--) {
		ret[i] = list[i + start];
	}
  return ret;
}
function fn(a,b,c) {
  let args = toArray(arguments, 1);
  console.log(args); // [ 2, 3 ]
}

fn(1,2,3)

7. extend

对象合并,将from合并到to对象中

/**
 * Mix properties into target object.
 * * 浅拷贝
 * 将属性混合到目标对象中。
 * 类似 Object.assgin()
 */

//对象浅拷贝,参数(to, _from)循环_from的值,会覆盖掉to的值
function extend(to, _from) {
	for (var key in _from) {
		to[key] = _from[key];
	}
	return to;
}
  1. extend使用
let o = { name: "前端", obj:{ name: "张三" } };

let b = extend({}, o);

b.name ="掘金打咯"
b.obj.name = "加油"
console.log(o); // { name: '前端', obj: { name: '加油' } }
console.log(b); // { name: '掘金', obj: { name: '加油' } }
  1. toObject
// 将对象数组合并成一个对象
function toObject(arr) {
  var res = {};
  for (var i = 0; i < arr.length; i++) {
    if(arr[i]) {
      extend(res, arr[i]);
    }
  }
  return res;
}

let arr = [  { name: "前端", obj:{ name: "张三" }, age: 19 },  { name: "手打", obj:{ name: "李四" } }]

console.log(toObject(arr)); // { name: '手打', obj: { name: '李四' }, age: 19 }

8. genStaticKeys

合并对象指定字符

/**
 * Generate a static keys string from compiler modules.
 *
 *    [{ staticKeys:1},{staticKeys:2},{staticKeys:3}]
 * 连接数组对象中的 staticKeys key值,连接成一个字符串 str=‘1,2,3’
 */
function genStaticKeys(modules) {
	return modules
		.reduce(function (keys, m) {
			//累加staticKeys的值变成数组
			return keys.concat(m.staticKeys || []);
		}, [])
		.join(","); //转换成字符串
}
let staticKeys = [{ staticKeys: 1 }, { staticKeys: 2 }, { staticKeys: 3 }];

console.log(genStaticKeys(staticKeys)); // 1,2,3

9. once

函数只会执行一次

/**
 * Ensure a function is called only once.
 *  确保该函数只调用一次 闭包函数
 */
function once(fn) {
	var called = false;
	return function () {
		if (!called) {
			called = true;
			return fn.apply(this, arguments);
		}
	};
}
add = (a, b) => {
	console.log("执行");
	return a + b;
};

let addOnce = once(add);
console.log(addOnce(1, 2));
console.log(addOnce(2,3));
执行 // add函数只会执行一次
3
undefined

配合 SnippestLab 的使用

image.png

image.png

image.png

软件详细介绍可以参考: sspai.com/post/30406

官网地址: www.renfei.org/snippets-la…

使用文档: www.renfei.org/snippets-la…