前端从哪里会用到函数的函数有哪些

在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
标签:至少1个,最多5个
一、函数调用的4种模式
(1) 方法调用模式
当一个函数被保存为对象的一个属性时,我们称它为一个方法。当一个方法被调用时,this 被绑定到该对象。如果调用表达式包含一个提取属性的动作(即包含一个.点表达式或[subscript]下标表达式),那么它就是被当做一个方法来调用。
var myObj = {
increment: function (inc) {
this.value += typeof inc === 'number' ? inc : 1;
myObj.increment();
console.log(myObj.value); // 1
myObj.increment(2);
console.log(myObj.value); // 3
(2) 函数调用模式
var add = function (a,b) {
return a +
var sum = add(3,4); // sum的值为7
以此模式调用函数时,this 被绑定到全局对象。
延伸:调用内部函数时,如何把 this 绑定到外部函数的 this 变量上
// 承接上面代码
// 给 myObj 增加一个 double 方法
myObj.double = function() {
var that = // 解决方法
var helper = function () {
console.log(this); // this指向全局对象,如果写成this.value = add(this.value, this.value); 就获取不到正确的结果了
that.value = add(that.value, that.value);
helper(); // 以函数的形式调用 helper
myObj.double(); // 以方法的形式调用 double
console.log(myObj.value); // 6
(3) 构造器调用模式
var Quo = function (string) {
this.status =
var myQuo = new Quo("confused"); // 构造一个 Quo 实例
console.log(myQuo.status); // "confused"
一个函数,如果创建的目的就是希望结合new前缀来调用,那它就被称为构造(器)函数,函数内部的this 指向新创建的实例。
(4) apply、call调用模式
js 是一门函数式的面向对象编程语言,函数也是一个对象,所以函数可以拥有自己的方法,apply、call就是其中的两种方法。
此种调用模式允许我们可以显式地设置 this 的指向,具体使用见下文。
二、函数常用的三个方法
1. fun.apply(thisArg[, argsArray])
在指定 this 值和参数(参数以数组或类数组对象的形式存在)的情况下调用某个函数。thisArg:在 fun 函数运行时指定的 this 值,如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动指向全局对象(浏览器中就是window对象)argsArray:一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 fun 函数。如果该参数的值为null 或 undefined,则表示不需要传入任何参数。也可以使用 arguments 对象作为 argsArray 参数,用arguments把所有的参数传递给被调用对象。
/* 求一个数组中的最大最小值 */
var numbers = [5, 6, 2, 3, 7];
/* simple loop based algorithm */
max = -Infinity, min = +I
for (var i = 0; i & numbers. i++) {
if (numbers[i] & max)
max = numbers[i];
if (numbers[i] & min)
min = numbers[i];
/* vs. using Math.min/Math.max apply */
var max = Math.max.apply(null, numbers); /* This about equal to Math.max(numbers[0], ...) or Math.max(5, 6, ..) */
var min = Math.min.apply(null, numbers);
从上面的例子可以看到:本来需要写成遍历数组变量的任务,apply使用内建的函数就完成了。据此,可以简化某些对数组的操作
var arr1 = [1,2,3];
var arr2 = [4,5,6];
/* 如果我们要把 arr2 展开,然后一个一个追加到 arr1 中去,最后让 arr1=[1,2,3,4,5,6]
* arr1.push(arr2)是不行的,因为这样做会得到[1,2,3,[4,5,6]]
* 可以循环arr2,然后一个一个的push,但是这样比较麻烦,使用apply,就so easy了
Array.prototype.push.apply(arr1,arr2);
console.log(arr1); // [1,2,3,4,5,6]
/* 也可以用arr1.concat(arr2),但是concat方法返回的是一个新数组,并不改变arr1本身 */
2. fun.call(thisArg[, arg1[, arg2[, ...]]])
该方法的作用和 apply() 方法类似,只有一个区别,就是 call() 方法接受的是一个参数列表,而apply()方法接受的是一个包含多个参数的数组。
Math.max.apply(null, [1,2,3,4]);
Math.max.call(null, 1, 2, 3, 4);
/* eg. 使用call方法调用父构造函数 */
function Animal(name){
this.name =
this.showName = function(){
console.log(this.name);
function Cat(name){
Animal.call(this, name); // 此行代码中的this指向Cat的实例
var cat = new Cat("Black Cat");
cat.showName(); // "Black Cat"
3. fun.bind(thisArg[, arg1[, arg2[, ...]]])
当在函数fun上调用bind( )方法并传入一个对象thisArg作为参数,这个方法将返回一个新函数。调用新的函数将会把原始的函数fun当做thisArg的方法来调用。thisArg:当绑定函数被调用时,该参数会作为原函数运行时的 this 指向。当使用new 操作符调用绑定函数时,该参数无效arg1, arg2, ...:当绑定函数被调用时,这些参数加上绑定函数本身的参数会按照顺序作为原函数运行时的参数
var sum = function (x,y) { return x + };
var succ = sum.bind(null, 1);
succ(2); // =& 3: x绑定到1,并传入2作为实参y
function f(y,z) { return this.x + y + };
var g = f.bind({x:1}, 2); // 绑定this和y
g(3); // =&6: this.x绑定到1,y绑定到2,z绑定到3
// eg.3 创建绑定函数
this.x = 9;
var module = {
getX: function() { return this.x; }
module.getX(); // 81
var retrieveX = module.getX;
retrieveX(); // 9, because in this case, "this" refers to the global object
// Create a new function with 'this' bound to module
var boundGetX = retrieveX.bind(module);
boundGetX(); // 81
bind 函数在ES5版本中才被加入,ES3版本的bind( )方法实现如下(js权威指南p191):
if (!Function.prototype.bind) {
Function.prototype.bind = function(o[, args]) {
var self = this, boundArgs =
// bind()方法的返回值是一个函数
return function() {
// 创建一个实参列表,将传入bind()的第二个及后续的实参都传入这个函数
var args = [],
for(i = 1; i & boundArgs. i++) args.push(boundArgs[i]);
for(i = 0; i & arguments. i++) args.push(arguments[i]);
// 现在将self作为o的方法来调用,传入这些实参
return self.apply(o, args);
/* 关键点有二:一是改变this的指向,二是改变传入参数的个数
* 上述代码并未实现ES5中bind方法的全部特性,但思路比较清晰明了,且满足大部分需求了
0 收藏&&|&&4
你可能感兴趣的文章
16 收藏,946
2 收藏,91
1 收藏,494
分享到微博?
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。前端常用的几种弹窗函数
时间: 22:21:59
&&&& 阅读:659
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&1、alert("") 弹窗:提示alert弹窗使我们写js时使用最多的一种弹窗,主要作为提示,一般我们经常用来测试js某段代码是否有没有出错。例://弹出对话框并输出一段提示信息 &function prompt() { && //弹出一个对话框 && alert("提示信息!"); &}2、confirm("")&弹窗:判断是否进行某一个操作confirm() 方法主要用于显示一个带有指定消息和 OK 及取消按钮的对话框。如用户点击确定按钮,则返回 true。如点击取消,则返回 false。在点击确定或取消按钮关闭之前,它将阻止用户对浏览器的所有输入。例://弹出一个询问框,有确定和取消按钮 &function firm() { && &//利用对话框返回的值 (true 或者 false) && &if (confirm("你确定提交吗?")) { && & & alert("点击了确定"); && & }&&&&else { && & & alert("点击了取消"); && & &} & &}3、prompt("")&弹窗:用于输入文本内容prompt("") 弹窗方法用于显示可提示用户进行输入的对话框。如用户单击取消按钮,则返回 null。如单击确认按钮,则返回输入的文本。在点击确定或取消关闭之前,它将阻止用户对浏览器的所有输入。在调用 prompt() 时,在用户作出响应之前,不会执行下一条语句。例://弹出一个输入框,输入一段文字,可以提交 &function prom() { && &var name = prompt("请输入您的名字", ""); //将输入的内容赋给变量 name , && &//这里需要注意的是,prompt有两个参数,前面是提示的话,后面是当对话框出来后,在对话框里的默认值 && & & if (name)//如果返回的有内容 && & & { && & & & &alert("欢迎您:" + name) && & & } &&}&本文出自 “” 博客,请务必保留此出处标签:&&&&&&&&&&&&原文地址:http://xhlsky.blog.51cto.com/9261
&&国之画&&&& &&&&chrome插件&&
版权所有 京ICP备号-2
迷上了代码!7 个基本的 JS 函数 - WEB前端 - 伯乐在线
& 7 个基本的 JS 函数
我记得早期的 JavaScript ,要完成任何事情几乎都绕不开一些简单的函数,因为浏览器提供商实现功能有所差异,而且不只是边缘功能,基础功能也一样,如 addEventListener 和 attachEvent。虽然时代变了,但仍有一些函数是每个开发者都应该掌握的,以便于完成某些功能和提高性能。
对于高耗能事件,debounce 函数是一种不错解决方案。如果你不对 scroll、resize、和 key* 事件使用 debounce
函数,那么你几乎等同于犯了错误。下面的 debounce 函数能让你的代码保持高效:
JavaScript
// 返回一个函数,如果它被不间断地调用,它将不会得到执行。该函数在停止调用 N 毫秒后,再次调用它才会得到执行。如果有传递 ‘immediate’ 参数,会马上将函数安排到执行队列中,而不会延迟。
function debounce(func, wait, immediate) {
return function() {
var context = this, args =
var later = function() {
if (!immediate) func.apply(context, args);
var callNow = immediate && !
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
var myEfficientFn = debounce(function() {
// 所有繁重的操作
window.addEventListener('resize', myEfficientFn);
123456789101112131415161718192021
// 返回一个函数,如果它被不间断地调用,它将不会得到执行。该函数在停止调用 N 毫秒后,再次调用它才会得到执行。如果有传递 ‘immediate’ 参数,会马上将函数安排到执行队列中,而不会延迟。function debounce(func, wait, immediate) { var timeout; return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args); };};&// 用法var myEfficientFn = debounce(function() {&&&&&&&&// 所有繁重的操作}, 250);window.addEventListener('resize', myEfficientFn);
debounce 函数不允许回调函数在指定时间内执行多于一次。当为一个会频繁触发的事件分配一个回调函数时,该函数显得尤为重要。
尽管上面我提及了 debounce 函数,但如果事件不存在时,你就不能插入一个事件以判断所需的状态,那么就需要每隔一段时间去检查状态是否达到你的要求。
JavaScript
function poll(fn, callback, errback, timeout, interval) {
var endTime = Number(new Date()) + (timeout || 2000);
interval = interval || 100;
(function p() {
// 如果条件满足,则执行!
if(fn()) {
callback();
// 如果条件不满足,但并未超时,再来一次
else if (Number(new Date()) & endTime) {
setTimeout(p, interval);
// 不匹配且时间消耗过长,则拒绝!
errback(new Error('timed out for ' + fn + ': ' + arguments));
// 用法:确保元素可见
function() {
return document.getElementById('lightbox').offsetWidth & 0;
function() {
// 执行,成功的回调函数
function() {
// 错误,失败的回调函数
1234567891011121314151617181920212223242526272829303132
function poll(fn, callback, errback, timeout, interval) {&&&&var endTime = Number(new Date()) + (timeout || 2000);&&&&interval = interval || 100;&&&&&(function p() {&&&&&&&&&&&&// 如果条件满足,则执行!&&&&&&&&&&&&if(fn()) {&&&&&&&&&&&&&&&&callback();&&&&&&&&&&&&}&&&&&&&&&&&&// 如果条件不满足,但并未超时,再来一次&&&&&&&&&&&&else if (Number(new Date()) & endTime) {&&&&&&&&&&&&&&&&setTimeout(p, interval);&&&&&&&&&&&&}&&&&&&&&&&&&// 不匹配且时间消耗过长,则拒绝!&&&&&&&&&&&&else {&&&&&&&&&&&&&&&&errback(new Error('timed out for ' + fn + ': ' + arguments));&&&&&&&&&&&&}&&&&})();}&// 用法:确保元素可见poll(&&&&function() {&&&&&&&&return document.getElementById('lightbox').offsetWidth & 0;&&&&},&&&&function() {&&&&&&&&// 执行,成功的回调函数&&&&},&&&&function() {&&&&&&&&// 错误,失败的回调函数&&&&});
Polling 在 web 中已被应用很长时间了,并在将来仍会被使用。
有时候,你想让一个给定的功能只发生一次,类似于 onload 事件。下面的代码提供了你所说的功能:
JavaScript
function once(fn, context) {
return function() {
result = fn.apply(context || this, arguments);
var canOnlyFireOnce = once(function() {
console.log('Fired!');
canOnlyFireOnce(); // "Fired!"
canOnlyFireOnce(); // nada
// 没有执行指定函数
123456789101112131415161718192021
function once(fn, context) {
var result;& return function() {
result = fn.apply(context || this, arguments);
fn = null;
return result; };}&// 用法var canOnlyFireOnce = once(function() { console.log('Fired!');});&canOnlyFireOnce(); // "Fired!"canOnlyFireOnce(); // nada&&&&&&&&&&&&&&&&&&&& // 没有执行指定函数
once 函数确保给定函数只能被调用一次,从而防止重复初始化!
从一个字符串变量得到一个绝对 URL,并不是你想象中这么简单。对于某些 URL 构造器,如果你不提供必要的参数就会出问题(而有时候你真的不知道提供什么参数)。下面有一个优雅的技巧,只需要你传递一个字符串就能得到相应的绝对 URL。
JavaScript
var getAbsoluteUrl = (function() {
return function(url) {
if(!a) a = document.createElement('a');
getAbsoluteUrl('/something'); // http://davidwalsh.name/something
12345678910111213
var getAbsoluteUrl = (function() { var a;& return function(url) {
if(!a) a = document.createElement('a');
a.href = url;&
return a.href; };})();&// 用法getAbsoluteUrl('/something'); // http://davidwalsh.name/something
a 元素的 href 处理和 url 处理看似无意义,而 return 语句返回了一个可靠的绝对 URL。
如果你想知道一个指定函数是否是原生的,或者能不能通过声明来覆盖它。下面这段便于使用的代码能给你答案:
JavaScript
;(function() {
// 用于处理传入参数 value 的内部&`[[Class]]`&
var toString = Object.prototype.toS
// 用于解析函数的反编译代码
var fnToString = Function.prototype.toS
// 用于检测宿主构造器 (Safari & 4 ;真的输出特定的数组)
var reHostCtor = /^[object .+?Constructor]$/;
// 用一个标准的原生方法作为模板,编译一个正则表达式。
// 我们选择 'Object#toString' 因为它一般不会被污染。
var reNative = RegExp('^' +
// 将 'Object#toString' 强制转为字符串
String(toString)
// 转义所有指定的正则表达式字符
.replace(/[.*+?^${}()|[]/]/g, '$&')
// 用 '.*?' 替换提及的 'toString' ,以保持模板的通用性。
// 将 'for ...' 之类的字符替换掉,以兼容 Rhino 等环境,因为这些环境添加了额外的信息,如方法参数数量。
.replace(/toString|(function).*?(?=()| for .+?(?=])/g, '$1.*?') + '$'
function isNative(value) {
var type =
return type == 'function'
// 用 'Function#toString' (fnToString)绕过了值(value)本身的 'toString' 方法,以免被伪造所欺骗。
? reNative.test(fnToString.call(value))
// 回退到宿主对象的检查,因为某些环境(浏览器)将类型数组(typed arrays)之类的东西当作 DOM 方法,此时可能不遵循标准的原生正则表达式。
: (value && type == 'object' && reHostCtor.test(toString.call(value))) ||
// 导出函数
module.exports = isN
isNative(alert); // true
isNative(myCustomFunction); // false
123456789101112131415161718192021222324252627282930313233343536373839
;(function() {&&&// 用于处理传入参数 value 的内部&`[[Class]]`&&&var toString = Object.prototype.toString;&&&// 用于解析函数的反编译代码&&var fnToString = Function.prototype.toString;&&&// 用于检测宿主构造器 (Safari & 4 ;真的输出特定的数组)&&var reHostCtor = /^[object .+?Constructor]$/;&&&// 用一个标准的原生方法作为模板,编译一个正则表达式。&&// 我们选择 'Object#toString' 因为它一般不会被污染。&&var reNative = RegExp('^' +&&&&// 将 'Object#toString' 强制转为字符串 &&&&String(toString)&&&&// 转义所有指定的正则表达式字符&&&&.replace(/[.*+?^${}()|[]/]/g, '$&')&&&&// 用 '.*?' 替换提及的 'toString' ,以保持模板的通用性。&&&&// 将 'for ...' 之类的字符替换掉,以兼容 Rhino 等环境,因为这些环境添加了额外的信息,如方法参数数量。&&&&.replace(/toString|(function).*?(?=()| for .+?(?=])/g, '$1.*?') + '$'&&);&&&function isNative(value) {&&&&var type = typeof value;&&&&return type == 'function'&&&&&&// 用 'Function#toString' (fnToString)绕过了值(value)本身的 'toString' 方法,以免被伪造所欺骗。&&&&&&? reNative.test(fnToString.call(value))&&&&&&// 回退到宿主对象的检查,因为某些环境(浏览器)将类型数组(typed arrays)之类的东西当作 DOM 方法,此时可能不遵循标准的原生正则表达式。&&&&&&: (value && type == 'object' && reHostCtor.test(toString.call(value))) || false;&&}&&&// 导出函数&&module.exports = isNative;}());&// 用法isNative(alert); // trueisNative(myCustomFunction); // false
这个函数虽不完美,但它能完成任务!
我们都知道能通过选择器(通过 document.querySelectorAll )获取一个 NodeList ,并可为每个元素设置样式,但有什么更高效的方法为选择器设置样式呢(例如你可以在样式表里完成):
JavaScript
var sheet = (function() {
// 创建 &style& 标签
var style = document.createElement('style');
// 如果你需要指定媒介类型,则可以在此添加一个 media (和/或 media query)
// style.setAttribute('media', 'screen')
// style.setAttribute('media', 'only screen and (max-width : 1024px)')
// WebKit hack :(
style.appendChild(document.createTextNode(''));
// 将 &style& 元素添加到页面
document.head.appendChild(style);
return style.
sheet.insertRule("header { float: opacity: 0.8; }", 1);
12345678910111213141516171819
var sheet = (function() {&&&&&&&&// 创建 &style& 标签 var style = document.createElement('style');&&&&&&&&&// 如果你需要指定媒介类型,则可以在此添加一个 media (和/或 media query)
// style.setAttribute('media', 'screen') // style.setAttribute('media', 'only screen and (max-width : 1024px)')& // WebKit hack :( style.appendChild(document.createTextNode(''));&&&&&&&&&// 将 &style& 元素添加到页面 document.head.appendChild(style);& return style.sheet;})();&// 用法sheet.insertRule("header { float: opacity: 0.8; }", 1);
这对于一个动态且重度依赖 AJAX 的网站来说是特别有用的。如果你为一个选择器设置样式,那么你就不需要为每个匹配到的元素都设置样式(现在或将来)。
我们经常会在进行下一步操作前进行输入校验,以确保是一个可靠值,或确保表单数据是有效的,等等。但我们平时是怎么确保一个元素是否有资格进行进一步操作呢?如果一个元素有给定匹配的选择器,那么你可以使用 matchesSelector 函数来校验:
JavaScript
function matchesSelector(el, selector) {
var p = Element.
var f = p.matches || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector || function(s) {
return [].indexOf.call(document.querySelectorAll(s), this) !== -1;
return f.call(el, selector);
matchesSelector(document.getElementById('myDiv'), 'div.someSelector[some-attribute=true]')
12345678910
function matchesSelector(el, selector) { var p = Element.prototype; var f = p.matches || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector || function(s) {
return [].indexOf.call(document.querySelectorAll(s), this) !== -1; }; return f.call(el, selector);}&// 用法matchesSelector(document.getElementById('myDiv'), 'div.someSelector[some-attribute=true]')
就这样啦,上述 7 个 JavaScript 函数是每个开发者都应该时刻记着的。有哪个函数我错过了呢?请把它分享出来!
打赏支持我翻译更多好文章,谢谢!
打赏支持我翻译更多好文章,谢谢!
任选一种支付方式
关于作者:
可能感兴趣的话题
good,good,学习中。。。菜鸟就应该多记!!!
关于伯乐前端
伯乐前端分享Web前端开发,包括JavaScript,CSS和HTML5开发技术,前端相关的行业动态。
新浪微博:
推荐微信号
(加好友请注明来意)
– 好的话题、有启发的回复、值得信赖的圈子
– 分享和发现有价值的内容与观点
– 为IT单身男女服务的征婚传播平台
– 优秀的工具资源导航
– 翻译传播优秀的外文文章
– 国内外的精选文章
– UI,网页,交互和用户体验
– 专注iOS技术分享
– 专注Android技术分享
– JavaScript, HTML5, CSS
– 专注Java技术分享
– 专注Python技术分享
& 2018 伯乐在线Lodash中十个常用的工具函数 - Web前端 - ITeye资讯
当你使用JavaScript进行编程的时候,你很可能需要经常重复写一些工具函数,尤其是处理字符串和对象。 即使ES6已经被标准化了,JavaScript开发者依然无法获得像Objective-C或Ruby那样多的语法糖。 因此,在JavaScript应用中仍然被重复的编写大量的工具函数。而本文将会为你带来的救星就是。
本文将要介绍的是Loadash中的10个常用的工具函数,当然对于不同的工作,你很可能也会需要其他的工具函数, 本文仅作为一个入门Lodash的引子,完整的函数列表请参考Lodash的。 本文使用的Lodash版本是3.10.1。
Statement
引用原文地址: http://colintoh.com/blog/lodash-10-javascript-utility-functions-stop-rewriting
循环N次
// 1. Basic for loop.
for(var i = 0; i & 5; i++) {
// 2. Using Array's join and split methods
Array.apply(null, Array(5)).forEach(function(){
_.times(5, function(){
for循环是一个常见的使用场景,但是它会引入附加变量污染作用域(scope)。 你可以组合使用数组和apply方法来避免直接使用for循环,这样也避免了作用域污染的问题。 但是,这种写法不够直观。Lodash总的_.times方法就非常的直观易用。
迭代数组并返回每一项中深度嵌套的属性
// Fetch the name of the first pet from each owner
var ownerArr = [{
"owner": "Colin",
"pets": [{"name":"dog1"}, {"name": "dog2"}]
"owner": "John",
"pets": [{"name":"dog3"}, {"name": "dog4"}]
// Array's map method.
ownerArr.map(function(owner){
return owner.pets[0].
_.map(ownerArr, 'pets[0].name');
Lodash中的map方法和JavaScript中原生的数组方法非常的像,但它还是有非常有用的升级。 你可以通过一个字符串而不是回调函数来导航到深度嵌套的对象属性。
创建一个大小为N的数组,并且为他们添加相同的前缀
// Create an array of length 6 and populate them with unique values. The value must be prefix with "ball_".
// eg. [ball_0, ball_1, ball_2, ball_3, ball_4, ball_5]
// Array's map method.
Array.apply(null, Array(6)).map(function(item, index){
return "ball_" +
_.times(6, _.uniqueId.bind(null, 'ball_'));
从前面的例子中我们已经知道了_.times的作用。如果你将它和_.uniqueId方法组合使用, 我们可以获得一个更简洁的解决方案。如果你不想重复的声明上下文,Lodash也提供了一个可选方案。
避免使用.bind(null,...)
_.times(6, _.partial(_.uniqueId, 'ball_'));
_.partial方法完成的工作和原生的bind()方法很类似,除了它假设当前的上下文为this。 因此,没必要再额外的指定上下文参数。
深度克隆JavaScript对象
var objA = {
"name": "colin"
// Normal method? Too long. See Stackoverflow for solution: http://stackoverflow.com/questions/4459928/how-to-deep-clone-in-javascript
var objB = _.cloneDeep(objA);
objB === objA // false
深度克隆JavaScript对象是困难的,并且也没有什么简单的解决方案。你可以使用原生的解决方案: JSON.parse(JSON.stringify(objectToClone))进行深度克隆。但是,这种方案仅在对象内部没有方法的时候才可行。
Lodash提供了_.cloneDeep方法来帮你简单的完成对象的深度克隆操作。当然,使用_.clone你还能灵活的指定克隆的深度。
在指定范围内获取一个随机值
// Get a random number between 15 and 20.
// Naive utility method
function getRandomNumber(min, max){
return Math.floor(Math.random() * (max - min)) +
getRandomNumber(15, 20);
_.random(15, 20);
Lodash中的random方法要比上面的原生方法更强大与灵活。你可以只传入一个参数作为最大值, 你也可以指定返回的结果为浮点数。
_.random(20); // Return random number between 0 to 20
_.random(15, 20, true); // Return random floating numbers between 15 and 20
// Adding extend function to Object.prototype
Object.prototype.extend = function(obj) {
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
this[i] = obj[i];
var objA = {"name": "colin", "car": "suzuki"};
var objB = {"name": "james", "age": 17};
objA.extend(objB);
objA; // {"name": "james", "age": 17, "car": "suzuki"};
_.assign(objA, objB);
_.assign方法也可以接收多个参数对象进行扩展。
var objA = {"name": "colin", "car": "suzuki"};
var objB = {"name": "james", "age": 17};
var objC = {"pet": "dog"};
_.assign(objA, objB, objC)
// {"name": "james", "car": "suzuki", "age": 17, "pet": "dog"}
去掉对象的某些属性
// Naive method: Remove an array of keys from object
Object.prototype.remove = function(arr) {
var that =
arr.forEach(function(key){
delete(that[key]);
var objA = {"name": "colin", "car": "suzuki", "age": 17};
objA.remove(['car', 'age']);
objA; // {"name": "colin"}
objA = _.omit(objA, ['car', 'age']); // {"name": "colin"}
原生的途径你只能传递数组作为参数。有时我们可能也想对字符串参数进行单个key的删除,甚至是传入一个比较器。
var objA = {"name": "colin", "car": "suzuki", "age": 17};
objA = _.omit(objA, 'car'); // {"name": "colin", "age": 17};
objA = _.omit(objA, _.isNumber); // {"name": "colin"};
你需要注意的是,_.omit方法会返回一个新的对象,而不会修改原来的对象。
从某个对象中选择部分属性组成新的对象
// Naive method: Returning a new object with selected properties
Object.prototype.pick = function(arr) {
var _this =
var obj = {};
arr.forEach(function(key){
obj[key] = _this[key];
var objA = {"name": "colin", "car": "suzuki", "age": 17};
var objB = objA.pick(['car', 'age']);
// {"car": "suzuki", "age": 17}
var objB = _.pick(objA, ['car', 'age']);
// {"car": "suzuki", "age": 17}
_.pick方法与_.omit方法正好相反,它会从对象中选择指定的属性组装成新的对象。 和_.omit一样,_.pick也会返回新的对象,并且能够传入字符串、数组、比较器函数。
从列表中随机的选择列表项
var luckyDraw = ["Colin", "John", "James", "Lily", "Mary"];
function pickRandomPerson(luckyDraw){
var index = Math.floor(Math.random() * (luckyDraw.length -1));
return luckyDraw[index];
pickRandomPerson(luckyDraw); // John
_.sample(luckyDraw); // Colin
此外,你也可以指定随机返回元素的个数。
var luckyDraw = ["Colin", "John", "James", "Lily", "Mary"];
// Lodash - Getting 2 random item
_.sample(luckyDraw, 2); // ['John','Lily']
JSON.parse的错误处理
// Using try-catch to handle the JSON.parse error
function parse(str){
return JSON.parse(str);
// With Lodash
function parseLodash(str){
return _.attempt(JSON.parse.bind(null, str));
parse('a'); // false
parseLodash('a'); // Return an error object
parse('{"name": "colin"}'); // Return {"name": "colin"}
parseLodash('{"name": "colin"}'); // Return {"name": "colin"}
当你使用JSON.parse时,请记住一定要进行错误处理。如果没有即使得进行处理, 很可能成为巨大的安全隐患。永远都不要假设你接收到的一定是正确有效的JSON对象。 取代原生的使用try...catch进行错误处理,你可以使用_.attempt方法。 如果出错的话,它会返回一个Error对象。
小结
Lodash能够为你解决非常多小的细节问题,推荐你在JavaScript项目中使用它,它能让你的代码看起来更加的精简, 也更加的健壮,帮你避免很多重复的应用逻辑。此外,Lodash也迫使我们以函数式的方式来思考编程。 我们可以将应用切分为若干个小且专注的模块。这种模块化能够提高我们应用程序在测试时的代码覆盖率。
本文转自:
相关资源推荐}

我要回帖

更多关于 从哪里会用到函数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信