你真的了解Array.keys的用法吗

定义:

方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中
属性名的排列顺序和使用 for...in 循环遍历该对象时返回的顺序一致 。
复制代码

那我们先来看下 for ... in的用法

var obj = {
    { name: zhangsan },
    { name: lisi },
    { name: wangwu }
    for (var i in obj) {
        console.log(i) // "1" "2" "3"
        console.log(typeof i) // string
        console.log(obj[i].name) // "zhangsan" "lisi" "wangwu"
    }
    // the same 
    Object.keys(obj) // ["1","2","3"]  ES5 or ES2015
}
复制代码

再看几个Array.keys的例子

// simple array
var arr = ['a', 'b', 'c'];
console.log(Object.keys(arr)); // console: ['0', '1', '2']


// array like object
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.keys(obj)); // console: ['0', '1', '2']

// array like object with random key ordering
var anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj)); // console: ['2', '7', '100']

// getFoo is a property which is not enumerable
var myObj = Object.create({}, {
  getFoo: {
    value: function () { return this.foo; }
  }
});
myObj.foo = 1;
console.log(Object.keys(myObj)); // console: ['foo']
复制代码

注意:

在ES5里,如果此方法的参数不是对象(而是一个原始值),那么它会抛出 TypeError。在ES2015中,非对象的参数将被强制转换为一个对象。

Object.keys("foo");
// TypeError: "foo" is not an object (ES5 code)

Object.keys("foo");
// ["0", "1", "2"]                   (ES2015 code)
复制代码

针对上面,还有要兼容较低版本的浏览器,我们必须要添加兼容支持Object.keys的方法

if (!Object.keys) {
  Object.keys = (function () {
    var hasOwnProperty = Object.prototype.hasOwnProperty,
        hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
        dontEnums = [
          'toString',
          'toLocaleString',
          'valueOf',
          'hasOwnProperty',
          'isPrototypeOf',
          'propertyIsEnumerable',
          'constructor'
        ],
        dontEnumsLength = dontEnums.length;

    return function (obj) {
      if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');

      var result = [];

      for (var prop in obj) {
        if (hasOwnProperty.call(obj, prop)) result.push(prop);
      }

      if (hasDontEnumBug) {
        for (var i=0; i < dontEnumsLength; i++) {
          if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
        }
      }
      return result;
    }
  })()
};
复制代码

上面的代码在IE7(也许IE8也是)下有个问题,就是如果传入一个来自其他 window 对象下的对象时,不可枚举的属性也会获取到。

扩展:Object.getOwnPropertyNames()

Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属
性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
复制代码
var arr = ["a", "b", "c"];
console.log(Object.getOwnPropertyNames(arr).sort()); // ["0", "1", "2", "length"]
console.log(Object.keys(arr); // ["0", "1", "2"]
复制代码

// 类数组对象
var obj = { 1: "a", 3: "b", 2: "c"};
console.log(Object.getOwnPropertyNames(obj).sort()); // ["0", "1", "2"]
// "the same"
console.log(Object.keys(arr); // ["0", "1", "2"]
复制代码

// 使用Array.forEach输出属性名和属性值
Object.getOwnPropertyNames(obj).forEach(function(val, idx, array) {
  console.log(val + " -> " + obj[val]);
});
// 输出
// 0 -> a
// 1 -> b
// 2 -> c

//不可枚举属性
var my_obj = Object.create({}, {
  getFoo: {
    value: function() { return this.foo; },
    enumerable: false
  }
});
my_obj.foo = 1;

console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]
复制代码

扩展:hasOwnProperty

方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性
复制代码
var obj = new Object()
obj.animal = 'dog'
obj.hasOwnProperty('animal') // true
console.log(obj.hasOwnProperty('animal')) // Output: false
function changeObj() {
    obj.people = obj.animal
    delete obj.animal
}
changeObj()
obj.hasOwnProperty('animal') // false
obj.hasOwnProperty('people') // true
console.log(obj.hasOwnProperty('animal')) // Output: false
复制代码

总结:Object.keys、for...in、Object.getOwnPropertyNames() 三者类似

参考:MDN

转载于:https://juejin.im/post/5c88d7bf6fb9a049ab0e7a08

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值