检测 _ 是 lodash 还是 underscore

12

如何判断_变量是否已经加载了lodash或者underscore库?

我正在一个环境中使用lodash库进行项目开发,但是有时候也会加载underscore库。

目前,我想到了以下方法:

/** 
 * lodash defines a variable PLACEHOLDER = '__lodash_placeholder__'
 * so check if that is defined / contains the string "lodash"
 */
if ( typeof( _.PLACEHOLDER ) == 'undefined' || _.PLACEHOLDER.indexOf( 'lodash' ) < 0 ) {
    // _ is underscore, do what I need to access lodash
}

重要更新: 上述代码不起作用!

是否有一种"权威"的方法来检测_是lodash还是underscore?

注:
这是一个特定的请求,要找到一种确定加载了lodash或underscore在_变量中的方法:
1. 我不能控制是否加载underscore。(lodash我控制的范围内,并且将始终加载)。
2. lodash/underscore的加载顺序无法依赖。
3. 加载的underscore版本可能会发生变化(它是CMS框架的一部分,可能会更新)。
4. Lodash 4.17.x有300多个函数。我的代码利用了许多lodash中的函数。
5. Lodash包含许多underscore没有的函数。
6. 某些同时存在于两个库中的函数具有不同的实现。


我能想到的唯一一件事就是 lodash 中存在而 underscore 中不存在的 _.VERSION - bhantol
2
@bhantol: 下划线库同样具有VERSION版本信息(至少它网站上的版本是这样的)。 - Felix Kling
1
isLodash = _.toString().indexOf('lodash') >=0 - bhantol
1
你能详细说明一下整个问题吗?这似乎与“浏览器 vs 特性检测”有些相似。你需要从 lodash 中获取一些 underscore 中没有的特定内容吗?或者你为什么需要知道它们之间的区别? - Felix Kling
1
我和 Felix 的想法一致。我认为你应该检测特性而不是实现源。由于可以进行导入的方式,可能会涉及到独立的函数,所以如果必须的话,请提前进行合理性检查,然后使用它们并期望它们按照文档中描述的方式工作。通常情况下,如果这是将要运行的方式,你应该对两个库都进行积极的单元测试。 - tadman
显示剩余6条评论
2个回答

6

和 @bhantol 提到的类似,有一个 迁移文档 列出了 lodash 与 underscore 不兼容的差异。这些可以使用吗?例如,

if ( typeof( _.invoke ) !== 'undefined' ){
    // it's lodash
}

但是,如果可能的话,根据@felix-kling和@tadman以及其他人的评论加强,将问题限制在特定功能(例如:特定方法)级别而不是整个库可能更可靠。


6
_.invoke在两个库中都可用。但是_.at会更好一些(仅在lodash v1及以后版本可用)。 - Jack
1
我已经将这个问题添加到了问题描述中,以帮助澄清:加载的underscore版本可能会更改(它是CMS框架的一部分,可能会更新),因此依赖于特定函数不存在似乎不可行。 - random_user_name
对于使用 amd 的任何人,_.__amdModuleName - undefined

2

问题中发布的代码无法正常工作,因为PLACEHOLDER是一个私有变量,在缩小时会被重命名。

因此,我已经根据评论中提到的“特性检测”概念进行了调整。请注意,如果未来版本的underscore将所有这些函数都合并在一起,或者lodash废弃任何这些函数,则此方法可能会失效:

var isLodash = false;
// If _ is defined and the function _.forEach exists then we know underscore OR lodash are in place
if ( 'undefined' != typeof(_) && 'function' == typeof(_.forEach) ) {
  // A small sample of some of the functions that exist in lodash but not underscore
  var funcs = [ 'get', 'set', 'at', 'cloneDeep' ];
  // Simplest if assume exists to start
  isLodash  = true;
  funcs.forEach( function ( func ) {
    // If just one of the functions do not exist, then not lodash
    isLodash = ('function' != typeof(_[ func ])) ? false : isLodash;
  } );
}

if ( isLodash ) {
  // We know that lodash is loaded in the _ variable
  console.log( 'Is lodash: ' + isLodash );
} else {
  // We know that lodash is NOT loaded
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.3/lodash.js"></script>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接