1. 类型检查小工具
JavaScript 不是强类型语言,对此我推荐的最佳解决方案是 TypeScript。但有时你只是想要一个简单的类型检查,这种时候 JavaScript 允许你使用“typeof”关键字。
“typeof”的问题在于,将其用于某些原语和函数时效果很好,但对于数组和对象来说,由于它们都被视为“对象”,因此很难把握它们之间的区别。
const isOfType = (() => { // create a plain object with no prototype const type = Object.create(null); // check for null type type.null = x => x === null; // check for undefined type type.undefined = x => x === undefined; // check for nil type. Either null or undefined type.nil = x => type.null(x) || type.undefined(x); // check for strings and string literal type. e.g: 's', "s", `str`, new String() type.string = x => !type.nil(x) && (typeof x === 'string' || x instanceof String); // check for number or number literal type. e.g: 12, 30.5, new Number() type.number = x => !type.nil(x) && (// NaN & Infinity have typeof "number" and this excludes that (!isNaN(x) && isFinite(x) && typeof x === 'number' ) || x instanceof Number); // check for boolean or boolean literal type. e.g: true, false, new Boolean() type.boolean = x => !type.nil(x) && (typeof x === 'boolean' || x instanceof Boolean); // check for array type type.array = x => !type.nil(x) && Array.isArray(x); // check for object or object literal type. e.g: {}, new Object(), Object.create(null) type.object = x => ({}).toString.call(x) === '[object Object]'; // check for provided type instance type.type = (x, X) => !type.nil(x) && x instanceof X; // check for set type type.set = x => type.type(x, Set); // check for map type type.map = x => type.type(x, Map); // check for date type type.date = x => type.type(x, Date); return type;})();
2. 检查是否为空
有时你需要知道某些内容是否为空,并根据结果决定要使用的方法,例如检查长度、大小或是否包含任何子元素。下面这个工具打包了这些功能,你可以用它检查 String、Object、Array、Map 和 Set 的大小。
function isEmpty(x) { if(Array.isArray(x) || typeof x === 'string' || x instanceof String ) { return x.length === 0; } if(x instanceof Map || x instanceof Set) { return x.size === 0; } if(({}).toString.call(x) === '[object Object]') { return Object.keys(x).length === 0; } return false;}
3. 获取列表最后一项
其他语言里这个功能被做成了可以在数组上调用的方法或函数,但在 JavaScript 里面,你得自己做点工作。
function lastItem(list) { if(Array.isArray(list)) { return list.slice(-1)[0]; } if(list instanceof Set) { return Array.from(list).slice(-1)[0]; } if(list instanceof Map) { return Array.from(list.values()).slice(-1)[0]; }}
4. 带有范围的随机数生成器
有时你需要生成随机数,但希望这些数字在一定范围内,那就可以用这个工具。
function randomNumber(max = 1, min = 0) { if(min >= max) { return max; } return Math.floor(Math.random() * (max - min) + min);}
5. 随机 ID 生成器
有时你只是需要一些 ID?除非你要的是更复杂的 ID 生成器(例如 UUID),否则用不着为此安装什么新库,下面这个选项足够了。你可以从当前时间(以毫秒为单位)或特定的整数和增量开始生成,也可以从字母生成 ID。
// create unique id starting from current time in milliseconds// incrementing it by 1 everytime requestedconst uniqueId = (() => { const id = (function*() { let mil = new Date().getTime(); while (true) yield mil += 1; })(); return () => id.next().value;})();// create unique incrementing id starting from provided value or zero// good for temporary things or things that id resetsconst uniqueIncrementingId = ((lastId = 0) => { const id = (function*() { let numb = lastId; while (true) yield numb += 1; })() return (length = 12) => `${id.next().value}`.padStart(length, '0');})();// create unique id from letters and numbersconst uniqueAlphaNumericId = (() => { const heyStack = '0123456789abcdefghijklmnopqrstuvwxyz'; const randomInt = () => Math.floor(Math.random() * Math.floor(heyStack.length)) return (length = 24) => Array.from({length}, () => heyStack[randomInt()]).join('');})();
6. 创建一个范围内的数字
Python 里我很喜欢的一个功能是 range 函数,而在 JavaScript 里我经常需要自己写这个功能。下面是一个简单的实现,非常适合 for…of 循环以及需要特定范围内数字的情况。
function range(maxOrStart, end = null, step = null) { if(!end) { return Array.from({length: maxOrStart}, (_, i) => i) } if(end <= maxOrStart) { return []; } if(step !== null) { return Array.from( {length: Math.ceil(((end - maxOrStart) / step))}, (_, i) => (i * step) + maxOrStart ); } return Array.from( {length: Math.ceil((end - maxOrStart))}, (_, i) => i + maxOrStart );}
7. 格式化 JSON 字符串,stringify 任何内容
我在使用 NodeJs 将对象记录到控制台时经常使用这种方法。JSON.stringify 方法需要第三个参数,该参数必须有多个空格以缩进行。第二个参数可以为 null,但你可以用它来处理 function、Set、Map、Symbol 之类 JSON.stringify 方法无法处理或完全忽略的内容。

const stringify = (() => { const replacer = (key, val) => { if(typeof val === 'symbol') { return val.toString(); } if(val instanceof Set) { return Array.from(val); } if(val instanceof Map) { return Array.from(val.entries()); } if(typeof val === 'function') { return val.toString(); } return val; } return (obj, spaces = 0) => JSON.stringify(obj, replacer, spaces)})();
8. 顺序执行 promise
如果你有一堆异步或普通函数都返回 promise,要求你一个接一个地执行,这个工具就会很有用。它会获取函数或 promise 列表,并使用数组 reduce 方法按顺序解析它们。
const asyncSequentializer = (() => { const toPromise = (x) => { if(x instanceof Promise) { // if promise just return it return x; } if(typeof x === 'function') { // if function is not async this will turn its result into a promise // if it is async this will await for the result return (async () => await x())(); } return Promise.resolve(x) } return (list) => { const results = []; return list .reduce((lastPromise, currentPromise) => { return lastPromise.then(res => { results.push(res); // collect the results return toPromise(currentPromise); }); }, toPromise(list.shift())) // collect the final result and return the array of results as resolved promise .then(res => Promise.resolve([...results, res])); }})();
9. 轮询数据
如果你需要持续检查数据更新,但系统中没有 WebSocket,则可以使用这个工具来执行操作。它非常适合上传文件时,想要持续检查文件是否已完成处理的情况,或者使用第三方 API(例如 dropbox 或 uber)并且想要持续检查过程是否完成或骑手是否到达目的地的情况。
async function poll(fn, validate, interval = 2500) { const resolver = async (resolve, reject) => { try { // catch any error thrown by the "fn" function const result = await fn(); // fn does not need to be asynchronous or return promise // call validator to see if the data is at the state to stop the polling const valid = validate(result); if (valid === true) { resolve(result); } else if (valid === false) { setTimeout(resolver, interval, resolve, reject); } // if validator returns anything other than "true" or "false" it stops polling } catch (e) { reject(e); } }; return new Promise(resolver);}
10. 等待所有 promise 完成
这个算不上是代码解决方案,更多是对 Promise API 的强化。这个 API 在不断进化,以前我还为“allSettled”“race”和“any”做了代码实现,现在直接用 API 的就好了。

11. 交换数组值的位置
ES6 开始,从数组中的不同位置交换值变得容易多了。这个做起来不难,但是了解一下也不错,
12. 条件对象键
我最喜欢这条技巧了,我在使用 React 更新状态时经常用它。你可以将条件包装在括号中来有条件地将一个键插入一个 spread 对象。
13. 使用变量作为对象键
当你有一个字符串变量,并想将其用作对象中的键以设置一个值时可以用它。
14. 检查对象里的键
这是一个很好的技巧,可以帮助你检查对象键。

15. 删除数组重复项
数组中经常有重复的值,你可以使用 Set 数据结构来消除它。它适用于许多数据类型,并且 set 有多种检查相等性的方法,很好用。对于不同实例或对象的情况,你还是可以使用 Set 来跟踪特定事物并过滤出重复的对象。

16. 在 ArrayforEach 中执行“break”和“continue”
我真的很喜欢使用数组“.forEach”方法,但有时我需要提早退出或继续进行下一个循环,而不想用 for...loop。你可以复制“continue”语句行为来提前返回,但如果要复制“break”行为,则需要使用数组“.some”方法。
17. 使用别名和默认值来销毁
Destructuring(销毁)是 JavaScript 最好用的功能之一,而且你可以使用“冒号”设置别名,并使用“等号”设置属性默认值。

18. 可选链和空值合并
深入检查对象属性并处理 null 和 undefined 值时,你可以使用几个非常好用的 JavaScript 功能来解决常见的问题。
19. 用函数扩展类
我经常对别人讲,JavaScript 类只是构造函数和底层的原型,不是像 Java 中那样的真实概念。一个证据是,你可以只使用一个构造函数来扩展一个类。在私有内容里这个很好用,在类里“#”这些看着很奇怪,并且用于 babel 或 WebPack 时,编译出来的代码更少。
20. 扩展构造函数
类的一个问题是你只能扩展一个其他类。使用构造函数,你可以使用多个构造函数来构成一个函数,这样就会灵活多了。你可以使用函数原型的.apply 或.call 方法来实现。你甚至可以只扩展函数的一部分,只要它是一个对象即可。
21. 循环任何内容有时,你需要循环任何可迭代的内容(Set、Map、Object、Array、String 等)。这个非常简单的 forEach 函数工具就可以做到这一点。如果回调返回 true,它将退出循环。
function forEach(list, callback) { const entries = Object.entries(list); let i = 0; const len = entries.length; for(;i < len; i++) { const res = callback(entries[i][1], entries[i][0], list); if(res === true) break; }}
22. 使函数参数为 required
这是一种确保函数调用了完成工作所需内容的绝佳方法。你可以使用默认参数值的特性来调用函数,然后就会抛出一个错误。如果调用该函数时带上了它需要的值,则该值将替换该函数,并且什么也不会发生。使用 undefined 调用也有相同的效果。
function required(argName = 'param') { throw new Error(`"${argName}" is required`)}function iHaveRequiredOptions(arg1 = required('arg1'), arg2 = 10) { console.log(arg1, arg2)}iHaveRequiredOptions(); // throws "arg1" is requirediHaveRequiredOptions(12); // prints 12, 10iHaveRequiredOptions(12, 24); // prints 12, 24iHaveRequiredOptions(undefined, 24); // throws "arg1" is required
23. 创建模块或单例
很多时候,你需要在加载时初始化某些内容,设置它需要的各种事物,然后就可以在应用程序中到处使用它,而无需再做什么补充工作。你可以使用 IIFE 函数来做到这一点,这个函数太好用了。这种模块模式用来隔离事物非常好用,它可以只暴露需要交互的内容。
24. 深度克隆对象开发人员通常会安装一些类似“lodash”的库来执行这一操作,但使用纯 JavaScript 来实现确实也很容易。这是一个简单的递归函数:只要是一个对象,就使用函数的构造器将其重新初始化为一个克隆,然后对所有属性重复该过程。
const deepClone = obj => { let clone = obj; if (obj && typeof obj === "object") { clone = new obj.constructor(); Object.getOwnPropertyNames(obj).forEach( prop => (clone[prop] = deepClone(obj[prop])) ); } return clone;};
25. 深度冻结对象
如果你喜欢不变性,那么这个工具你一定要常备。
const deepClone = obj => { let clone = obj; if (obj && typeof obj === "object") { clone = new obj.constructor(); Object.getOwnPropertyNames(obj).forEach( prop => (clone[prop] = deepClone(obj[prop])) ); } return clone;};
JSON.stringify 替换参数的威力

let str = 'adfdf DD ssFF'
let reverseCase = (str) => {
let res = [...str].map(item => {
return item === item.toLowerCase() ? item.toUpperCase() : item.toLowerCase()
}).join('')
return res
}
console.log(reverseCase(str)) //ADFDF dd SSff
let str = 'i am shi niu bi ren'
let res = str.replace(/\b[a-z]/g, (str) => { return str.toUpperCase() })
console.log(res) //I Am Shi Niu Bi Ren
const arr = [2, 4, 5, 6, 1, 7, 8, 9, 0, 3]
arr.sort((a, b) => {
return Math.random() - 0.5
})
console.log(arr)
const arr = [2, 4, 5, 6, 1, 7, 8, 9, 0, 3]
let res = arr.reduce((pre, cur) => {
let res = cur > pre ? cur : pre
return res
})
console.log(res)//9
let res2 = Math.max(...arr)
console.log(res2)//9
const arr = [2, 4, 5, 6, 1, 7, 8, 9, 0, 3]
let getRandomValue = (array) => {
return array[Math.floor(Math.random() * array.length)]
}
console.log(getRandomValue(arr))
let str1 = 'abcdcba'
let str2 = 'edcabaa'
let compare = (str) => {
return str.split('').reverse().join('') === str
}
console.log(compare(str2)) //false
const arr = [11, 2, 2, 33, 11, 88, 33, 99]
const arr1 = [11, 2, 33, 88, 99]
let repetition = (arr) => {
return new Set(arr).size !== arr.length
}
console.log(repetition(arr)) //true
let arr = ["a", "b", "c", "f", "b", "b", " b", "d", "d"]
let count = (arr) => {
let res = arr.reduce((preArr, curItem) => {
preArr[curItem] = preArr[curItem] ? preArr[curItem] + 1 : 1
return preArr
}, {})
return res
}
console.log(count(arr))//{ a: 1, b: 3, c: 1, f: 1, ' b': 1, d: 2 }
let arr1 = [null, 1, 2]
let arr2 = [undefined, 1, 2]
console.log((arr1.length === arr2.length) && (arr1.every((item, index) => {
return item === arr2[index]
})))
动漫制作技巧是很多新人想了解的问题,今天小编就来解答与大家分享一下动漫制作流程,为了帮助有兴趣的同学理解,大多数人会选择动漫培训机构,那么今天小编就带大家来看看动漫制作要掌握哪些技巧?一、动漫作品首先完成草图设计和原型制作。设计草图要有目的、有对象、有步骤、要形象、要简单、符合实际。设计图要一致性,以保证制作的顺利进行。二、原型制作是根据设计图纸和制作材料,可以是手绘也可以是3d软件创建。在此步骤中,要注意的问题是色彩和平面布局。三、动漫制作制作完成后,加工成型。完成不同的表现形式后,就要对设计稿进行加工处理,使加工的难易度降低,并得到一些基本准确的概念,以便于后续的大样、准确的尺寸制定。四、
我开始了一个新的Rails3.2.5项目,Assets管道不再工作了。CSS和Javascript文件不再编译。这是尝试生成Assets时日志的输出:StartedGET"/assets/application.css?body=1"for127.0.0.1at2012-06-1623:59:11-0700Servedasset/application.css-200OK(0ms)[2012-06-1623:59:11]ERRORNoMethodError:undefinedmethod`each'fornil:NilClass/Users/greg/.rbenv/versions/1
rails新手。只是想了解\assests目录中的这两个文件。例如,application.js文件有如下行://=requirejquery//=requirejquery_ujs//=require_tree.我理解require_tree。只是将所有JS文件添加到当前目录中。根据上下文,我可以看出requirejquery添加了jQuery库。但是它从哪里得到这些jQuery库呢?我没有在我的Assets文件夹中看到任何jquery.js文件——或者直接在我的整个应用程序中没有看到任何jquery.js文件?同样,我正在按照一些说明安装TwitterBootstrap(http:
我有一个包含多个组件的存储库,其中大部分是用JavaScript(Node.js)编写的,一个是用Ruby(RubyonRails)编写的。我想要一个.travis.yml文件来触发一个运行每个组件的所有测试的构建。根据thisTravisCIGoogleGroupthread,目前还没有官方支持。我的目录结构是这样的:.├──构建服务器├──核心├──扩展├──网络应用├──流浪文件├──package.json├──.travis.yml└──生成文件我希望能够运行特定版本的Ruby(2.2.2)和Node.js(0.12.2)。我已经有了一个make目标,所以maketest在每
写在之前Shader变体、Shader属性定义技巧、自定义材质面板,这三个知识点任何一个单拿出来都是一套知识体系,不能一概而论,本文章目的在于将学习和实际工作中遇见的问题进行总结,类似于网络笔记之用,方便后续回顾查看,如有以偏概全、不祥不尽之处,还望海涵。1、Shader变体先看一段代码......Properties{ [KeywordEnum(on,off)]USL_USE_COL("IsUseColorMixTex?",int)=0 [Toggle(IS_RED_ON)]_IsRed("IsRed?",int)=0}......//中间省略,后续会有完整代码 #pragmamulti_c
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。多年来,我一直在使用多种语言进行编程,并且认为自己总体上相当擅长。但是,我从未编写过任何自动化测试:没有单元测试,没有TDD,没有BDD,什么都没有。我已经尝试开始为我的项目编写适当的测试套件。我可以看到在进行任何更改后能够自动测试项目中所有代码的理论值(value)。我可以看到像RSpec和Mocha这样的测试框架应该如何使设置和运行所述测试变得相当容易
我需要一些指导来了解如何将Angular整合到rails中。选择Rails的原因:我喜欢他们偏执的做事方式。还有迁移,gem真的很酷。使用angular的原因:我正在研究和寻找最适合SPA的框架。Backbone似乎太抽象了。我不得不在Angular和Ember之间做出选择。我首先开始阅读Angular,它对我来说很有意义。所以我从来没有去读过关于ember的文章。使用Angular和Rails的原因:我研究并尝试使用小型框架,例如grape、slim(是的,我也使用php)。但我觉得需要坚持项目的长期范围。我个人喜欢用Rails的方式做事。这就是我需要帮助的地方,我在Rails4中有
目标:我想从动画GIF中抓取最佳帧并将其用作静态预览图像。我相信最好的帧是显示最多内容的帧-不一定是第一帧或最后一帧。以这张动图为例:--这是第一帧:--这是第28帧:很明显,第28帧很好地代表了整个GIF。我如何以编程方式确定一帧是否比另一帧具有更多像素/内容?如果您能向我指出任何想法、想法、包/模块或文章,我们将不胜感激。 最佳答案 实现此目的的一种直接方法是估计entropy每个图像的帧,并选择具有最大熵的帧。在信息论中,熵可以被认为是图像的“随机性”。单一颜色的图像是非常可预测的,分布越平坦,越随机。这与Arthur-R描述
我正在尝试在一个新元素中测试less.js。我100%确定javascript文件加载正常,但我的css文件夹中的less文件一直出现此错误。我打算在启动之前使用less.app编译它,但我宁愿让less.js在开发期间进行编译。由于它是.less或其他文件而不允许浏览器访问该文件是否存在问题?谢谢(运行ubuntu11.04和rubyv1.9.2,在firefox和chrome中同样的错误)这是我的head.haml文件,我在其中链接到less.js和app.less(它们都在正确的文件夹中)%link{:rel=>"stylesheet/less",:type=>"text/c
我正在OSX10.13.4上使用Rails3.2.22.4、Ruby2.2.7开发一个应用程序。有多个翻译文件,例如。en.yml,sq.yml基于国家。从下面的rubymine执行命令时,加载网页时出现错误。rake--tracei18n:js:export来自en.yml的yaml内容已经过验证并且是正确的。从文件中删除后引发错误的特定行将在其他一些.yml文件中给出错误。正在使用当前版本的gemi18n(0.9.5)。Rails服务器启动但加载Web应用程序第一页时因同样的错误而中断。代码遇到i18n翻译代码时抛出错误,当错误从一个文件转移到另一个文件时,yml格式不是问题。