获取Object的属性可以通过Object.key或者for in语句去获取,获取到的属性都是可枚举属性。

    1. <script>
    2. var obj = {name: 'David'};
    3. obj.toString = 1;
    4. //在IEbug情况下,obj.toString依然是输出1,但是这个属性是不可枚举的,通过Object.keys找不到
    5. console.log(obj.toString);
    6. </script>
    1. var _ = {};
    2. _.isObject() = function(object) {
    3. return toString.call(object) === "[object Object]";
    4. };
    5. var hasOwnProperty = Object.hasOwnProperty;
    6. _.has = function(object, key) {
    7. return object != null && hasOwnProperty.call(object, key);
    8. };
    9. // 判断是否有bug,对象{toString: 1}的自身属性toString,应该是一个可枚举属性;如果不是,则表明是bug
    10. // {toString: 1}.toString 的值依然是1,只是toString属性不可枚举,找不到这个属性了;
    11. var hasEnumBug = ({toString: 1}).propertyIsEnumable(toString) === false;
    12. var properties = ["constructor", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString", "toString","valueOf"];
    13. // keys
    14. _.keys = function(object) {
    15. var result = [];
    16. if(!_.isObject(object)) {
    17. return result;
    18. }
    19. // 有bug的处理
    20. if(hasEnumBug) {
    21. for(var i; i< properties.length; i++) {
    22. var prop = properties[i];
    23. // object原型上的的属性被修改过后,object[prop]就不等于原型上的属性
    24. if(object[prop] !== Object.prototype[prop]) {
    25. result.push(prop);
    26. }
    27. }
    28. }
    29. //keys
    30. if(Object.keys) {
    31. return Object.keys(object);
    32. }
    33. // for in
    34. for(var key in object) {
    35. result.push(key);
    36. }
    37. return result;
    38. };

    例子1, 2, 3:

    1. 怎样监听对象属性的变化;
    2. 函数缓存;
    3. 监听数组对象的变化;

      1. //原型链
      2. // 代理原型, Vue,响应式系统
      3. // 例子1
      4. var obj = {};
      5. Object.defineProperty(obj, 'name', {
      6. get() {
      7. console.log('111111');
      8. },
      9. set(value) {
      10. console.log(value);
      11. }
      12. });
      13. obj.name = 'David';
      14. // 例子2
      15. function fn() {
      16. console.log('111');
      17. }
      18. var wait = fn;
      19. fn = function() {
      20. console.log('000');
      21. wait();
      22. };
      23. fn();
      24. // 例子3: 代理原型,检测数组变化
      25. var ProxyMethods = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort'];
      26. var arrProto = Array.prototype;
      27. var obj = Object.create(arrProto);
      28. ProxyMethods.forEach((method) => {
      29. obj[method] = function() {
      30. console.log('我检测到了' + method);
      31. var ret = arrProto[method].apply(this, arguments);
      32. return ret;
      33. };
      34. });
      35. var arr = [];
      36. arr.__proto__ = obj;
      37. arr.push(11);
      38. console.log(arr);
      39. arr.push(8);
      40. arr.push(7);
      41. arr.sort(function(a, b) {
      42. return a - b;
      43. });
      44. console.log(arr);

    createAssigner:

    1. // 判断是否有bug,对象{toString: 1}的自身属性toString,应该是一个可枚举属性;如果不是,则表明是bug
    2. // {toString: 1}.toString 的值依然是1,只是toString属性不可枚举,找不到这个属性了;
    3. var hasEnumBug = ({toString: 1}).propertyIsEnumerable('toString') === false;
    4. var properties = ["constructor", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString", "toString","valueOf"];
    5. // keys:获取object上所有的属性(自身可枚举属性)
    6. _.keys = function(object) {
    7. var result = [];
    8. if(!_.isObject(object)) {
    9. return result;
    10. }
    11. //判断浏览器是否支持Object.keys,优先使用Object.keys
    12. if (Object.keys) {
    13. return Object.keys(object);
    14. }
    15. // for in
    16. for(var key in object) {
    17. result.push(key);
    18. }
    19. // 有bug的处理
    20. if(hasEnumBug) {
    21. for(var i; i< properties.length; i++) {
    22. var prop = properties[i];
    23. // object原型上的的属性被修改过后,object[prop]就不等于原型上的属性
    24. if(object[prop] !== Object.prototype[prop]) {
    25. result.push(prop);
    26. }
    27. }
    28. }
    29. return result;
    30. };
    31. // allKeys:获取object上所有的属性(自身可枚举属性 + 原型链上可枚举的属性)
    32. _.allKeys = function(object) {
    33. var result = [];
    34. if(!_.isObject(object)) {
    35. return result;
    36. }
    37. // for in
    38. for(var key in object) {
    39. result.push(key);
    40. }
    41. // 有bug的处理
    42. if(hasEnumBug) {
    43. for(var i; i< properties.length; i++) {
    44. var prop = properties[i];
    45. // object原型上的的属性被修改过后,object[prop]就不等于原型上的属性
    46. if(object[prop] !== Object.prototype[prop]) {
    47. result.push(prop);
    48. }
    49. }
    50. }
    51. return result;
    52. };
    53. var createAssinger = function(func){
    54. return function(obj) {
    55. var length = arguments.length;
    56. //
    57. if (length < 2 || obj == null) {
    58. return obj;
    59. }
    60. for (var i=1; i<length; i++) {
    61. //获取第二个参数
    62. var source = arguments[i];
    63. var keys = func(source);
    64. var sLength = keys.length;
    65. for (var j=0; j < sLength; j++) {
    66. var key = keys[j];
    67. obj[key] = source[key];
    68. }
    69. }
    70. return obj;
    71. };
    72. };
    73. _.extend = createAssinger(_.allKeys);
    74. _.extendOwn = createAssinger(_.keys);