笔记:js对象遍历

JavaScript中的对象观点异常差别,要把它看成别的言语的关联数组(如PHP)或许Map(如Java)来明白的话,照样有很大的不一样——因为原型链属性描述符(主如果[[Enumerable]])的存在。

一个对象字面量{}Object作为原型,它有继续自原型链的不可罗列的toString要领。下面将以对象字面量为例。

  • 下标操作符、点操作符能够接见到本身属性或继续自原型链的任何属性,除非涌现了属性掩盖
    var a ={}; a.toString返回toString要领
    var a ={toString:"a"}; a.toString返回字符串”a”

  • for in轮回将罗列的本身属性和继续自原型链的一切[[Enumerable]]的属性

  • "key" in obj的推断中,推断本身属性或继续自原型链的属性的存在性
    "toString" in {}返回true

  • obj.hasOwnProperty()的推断中,只推断本身属性的存在性
    ({}).hasOwnProperty("toString")返回false
    ({toString:"a"}).hasOwnProperty("toString")返回true

  • Object.keys()可返回本身[[Enumerable]]的属性构成的数组,不包括原型链上继续的属性
    Object.keys({a:1})返回["a"],不包括原型链上的toString等内容

  • Object.getOwnPropertyNames()能够返回本身任何属性构成的数组,不包括原型链上继续的属性

类目语句本身属性原型链上继续的属性
可罗列属性不可罗列属性可罗列属性不可罗列属性
接见obj.prop
obj[“prop”]
轮回for key in obj
推断key in objTRUETRUETRUETRUE
obj.hasOwnProperty(key)TRUETRUEFALSEFALSE
枚举Object.keys(obj)
Object.getOwnPropertyNames(obj)

能够经由过程以下体式格局防止遍历过程当中的原型链滋扰:

  • 在get/set要领中为每个键加上前缀

  • Object.create(null)来建立一个没有原型的对象

这些都能够在StringMap的解决方案里找到:
(虽然很不喜好粘代码,然则google code都快关了)

// Copyright (C) 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Implements StringMap - a map api for strings.
 *
 * @author Mark S. Miller
 * @author Jasvir Nagra
 * @requires ses
 * @overrides StringMap
 */

var StringMap;

(function() {
   'use strict';

   var create = Object.create;
   var freeze = Object.freeze;
   function constFunc(func) {
     func.prototype = null;
     return freeze(func);
   }

   function assertString(x) {
     if ('string' !== typeof(x)) {
       throw new TypeError('Not a string: ' + x);
     }
     return x;
   }

   var createNull;

   if (typeof ses === 'undefined' ||
       !ses.ok() ||
       ses.es5ProblemReports.FREEZING_BREAKS_PROTOTYPES.beforeFailure) {

     // Object.create(null) may be broken; fall back to ES3-style implementation
     // (safe because we suffix keys anyway).
     createNull = function() { return {}; };
   } else {
     createNull = function() { return Object.create(null); };
   }

   StringMap = function StringMap() {

     var objAsMap = createNull();

     return freeze({
       get: constFunc(function(key) {
         return objAsMap[assertString(key) + '$'];
       }),
       set: constFunc(function(key, value) {
         objAsMap[assertString(key) + '$'] = value;
       }),
       has: constFunc(function(key) {
         return (assertString(key) + '$') in objAsMap;
       }),
       'delete': constFunc(function(key) {
         return delete objAsMap[assertString(key) + '$'];
       })
     });
   };

 })();
    原文作者:Humphry
    原文地址: https://segmentfault.com/a/1190000002425003
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞