当前位置:  开发笔记 > 编程语言 > 正文

为什么lodash的.isObject,.isPlainObject的行为与"typeof x ==='object'"不同?

如何解决《为什么lodash的.isObject,.isPlainObject的行为与"typeofx==='object'"不同?》经验,为你挑选了2个好方法。

考虑以下:

var o1 = {}
var O = function () {
  return this
}
var o2 = new O()
var o3 = function() {}
var o4 = [o1, o1]

var output = [
    [_.isObject(o1), _.isObject(o2), _.isObject(o3), _.isObject(o4)], 
    [_.isPlainObject(o1), _.isPlainObject(o2), _.isPlainObject(o3), _.isPlainObject(o4)],
    [typeof o1 === 'object', typeof o2 === 'object', typeof o3 === 'object', typeof o4 === 'object'],
    [o1 instanceof Array, o2 instanceof Array, o3 instanceof Array, o4 instanceof Array]
]

/* outputs:

[
    [true,true,true,true],
    [true,false,false,false],
    [true,true,false,true],
    [false,false,false,true]
]

*/

很明显,我们可以看到.isObject():

哪个检查value是否是Object的语言类型.(例如数组,函数,对象,正则表达式,新的Number(0)和new String('')

.isPlainObject():

其中,如果值是一个普通的对象,即,由所述对象的构造或一个用空的原型创建的对象

我们的好朋友,可靠的朋友typeof x === 'object'.

我有三个问题:

    有没有一个有意识的设计决定制作.isObject.isPlainObject行为不同于本机.js类型检查?

    如果我的第一个问题是真的,那么设计决策是什么,以这种方式做到这一点有什么好处?

    是否存在任何与lodash(或underscore.js)is*函数完全相同的函数typeof x === 'object'

显然我可以继续使用typeof,但从语法上讲,在某些地方使用一个或另一个有点奇怪,例如.isObject在检查时使用会返回误报typeof x === 'object' && typeof x !== 'function'.我真的没有看到.isObject.isFunction已经存在的情况下为函数返回true的任何好处.



1> djechlin..:

typeof与某物是否是物体无关.函数,字符串和它们都是{}不同的typeof,它们都是对象.函数当然是第一类对象,就像字符串是第一类对象一样,因此isObject必须为字符串和对象返回true.

为了记录,文档涵盖了这个:

检查value是否是Object的语言类型.(例如数组,函数,对象,正则表达式,新的Number(0)和new String(''))

哇!如果没有方便的isObject方法,那真的有很多东西需要测试.最公平的回报typeofobject,但更高级别的方法,尤其是像lodash这样的图书馆,是程序员可以忘记那些废话.

如果你关心typeof一个参数,那就用吧typeof.如果你关心不是函数的对象,你有几个选择:你可以特别使用typeof 检查字符串,或者你可以使用isObject && !isFunction.我更喜欢后者.后者确实恰好说出了你想传达的内容,所以编码是正确的.如果你认为当你说"对象"时你隐含的意思不是函数,那么你不认为函数是一等对象,或者你更希望你的代码更接近于它们不是的语言.但是你不能责怪lodash作为一个广泛使用函数是第一类对象的事实的库来创建一种语言,其中函数是第一类对象更具表现力.

我相信这是你的大部分问题.我相信用例isPlainObject是回答"这只是数据吗?"的问题.或者"是这个代码吗?" 所以创建为伪类(对象)的对象new不计算在内.



2> Ethan Lynn..:

有时代码比言语更响亮.这是来自lodash的来源:

function isObject(value) {
  var type = typeof value;
  return !!value && (type == 'object' || type == 'function');
}
function isPlainObject(value) {
  var Ctor;
  if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isHostObject(value) && !isArguments(value)) ||
      (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {
    return false;
  }
  var result;
  if (lodash.support.ownLast) {
    baseForIn(value, function(subValue, key, object) {
      result = hasOwnProperty.call(object, key);
      return false;
    });
    return result !== false;
  }
  baseForIn(value, function(subValue, key) {
    result = key;
  });
  return result === undefined || hasOwnProperty.call(value, result);
}

根据lodash文档:

则IsObject

检查value是否是Object 的语言类型.(例如数组,函数,对象,正则表达式,新的Number(0)和new String(''))

isPlainObject

检查value是否是普通对象,即Object构造函数创建的对象或[[Prototype]]为null的对象.

什么是对象?

也许isObject在JavaScript中存在一个函数本质上有点令人困惑,所以很多东西就像对象一样.关键思想是JavaScript中的某些值被视为原始值,而其他值则被视为完整的对象.字符串,数字和布尔值在内部级别的处理方式与使用对象文字或构造函数创建的对象的处理方式不同(这最终没有太多实际意义,因为基元会在必要时自动将其自身转换为对象).

事实typeof null === 'object'可能源于对象是引用类型的事实,并且通常从函数返回null来代替对象.(一个怪癖可能会回到指针的概念和C和C++中的NULLPTR.类型void *有很多值,但NULLPTR仍然被认为是指针类型的有效值.)

推荐阅读
臭小子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有