关于前端:理论实践从原型链到继承模式掌握-Object-的精髓一

39次阅读

共计 4401 个字符,预计需要花费 12 分钟才能阅读完成。

前言

系列首发于公众号『前端进阶圈』,若不想错过更多精彩内容,请“星标”一下,敬请关注公众号最新消息。

实践 + 实际:从原型链到继承模式,把握 Object 的精华(一)

  • 在之前的文章中,咱们介绍了函数调用地位的不同造成了 this 绑定对象的不同,但对象到底是什么?为什么咱们须要绑定他们呢?

    语法

  • 对象一共有两种语法:定义 (文字) 模式和结构模式。

    // 对象的文字语法大略是这样:var myObj = {
    key: value
    // ...
    };
    
    // 结构模式大略是这样:var myObj = new Object();
    myObj.key = value;
  • 结构模式和文字模式生成的对象是一样的,惟一的区别在于,在文字申明中你能够增加多个键值对,但在结构模式中你必须一一增加属性。

类型

  • JavaScript 一种有 6 中次要类型。

    • string
    • number
    • boolean
    • null
    • undefined
    • object
  • 其中,简略根本类型(string,boolean,number,null,undefined) 自身不是对象。null 会被当做一种对象类型,只是语言自身的一个 bug,即对 null 执行 typeof null 时会返回字符串 object。但实际上,null 自身就是根本类型。
  • 在 JavaScript 中有一种谬误的说法:JavaScript 中的万物皆对象。

内置对象

• String
• Number
• Boolean
• Object
• Function
• Array
• Date
• RegExp
• Error
  • 在 JavaScript 中,为什么 typeof null 会返回 object?

    • 因为不同的对象在底层都示意为二进制,在 JavaScript 中二进制前三位都是 0 的话会被判断为 object 类型,null 的二进制示意是全 0,天然前三位也是 0,所以执行 typeof 时会返回 object。

内容

  • 在对象中,咱们都晓得每个对象都有属性,但存储在对象容器内容的是这些属性的名称,他们就像指针 (技术角度来说是援用) 一样,指向这些值真正的存储地位。

    var myObject = {a: 2};
    
    myObject.a; // 2
    
    myObject["a"]; // 2
  • 上述形式中,应用 . 操作符被称为属性拜访,[] 操作符被称为键拜访。

    属性描述符

  • 在 ES5 之前,JS 没有提供给检测属性个性的办法,比方判断属性是否只读。

    var myObject = {a:2};
    
    Object.getOwnPropertyDescriptor(myObject, "a");
    // {
    //    value: 2,
    //    writable: true, 是否可写
    //    enumerable: true, 是否可枚举
    //    configurable: true 是否可配置
    // }
  • 须要留神的是,即使 configurable: false,但咱们还是能够把 writable 的状态从 true 改为 false, 然而无奈由 false 改为 true。除了无奈批改,configurable: false 这个属性还会禁止删除这个属性。

    var myObject = {a:2};
    
    myObject.a; // 2
    
    delete myObject.a;
    myObject.a; // undefined
    
    Object.defineProperty( myObject, "a", {
    value: 2,
    writable: true,
    configurable: false,
    enumerable: true
    } );
    
    myObject.a; // 2
    delete myObject.a;
    myObject.a; // 2

    不变性

  • 对象常量:联合 writable: false 和 configurable: false 即可创立一个真正的常量属性。(不可批改,重定义或删除)

    var myObject = {};
    
    Object.defineProperty( myObject, "FAVORITE_NUMBER", {
    value: 42,
    writable: false,
    configurable: false
    } );
  • 禁止扩大: 若想禁止一个对象增加新属性并且保留已有属性,可应用 Object.preventExtensions(…)“

    • 非严格模式下,创立属性 b 会静默失败。在严格模式下,将会抛出 TypeError 谬误。

      var myObject = {a:2};
      
      Object.preventExtensions(myObject);
      
      myObject.b = 3;
      myObject.b; // undefined
  • 密封:Object.seal(..) 会创立一个“密封”的对象,这个办法实际上会在一个现有对象上调用。Object.preventExtensions(..) 会把所有现有属性标记为 configurable:false。

    • 故密封之后不仅不能增加新属性,也不能重新配置或删除现有属性(尽管可批改属性的值)。`
  1. 解冻:Object.freeze(..) 会创立一个解冻对象,这个办法实际上会在一个现有对象上调用 Object.seal(..) 并把所有“数据拜访”属性标记为 writable:false,这样就无奈批改它们的值。

    存在性

  2. 在属性中属性返回可能是 undefined。但有可能属性中有可能贮存的就是 undefined, 也有可能是因为属性不存在就返回 undefined。那如何辨别呢?
  3. 可在不拜访属性值的状况下判断对象中是否存在这个属性:

    var myObject = {a:2};
    
    ("a" in myObject); // true
    ("b" in myObject); // false
    
    myObject.hasOwnProperty("a"); // true
    myObject.hasOwnProperty("b"); // false
  4. in 操作符会查看属性是否在对象及其[[prototype]] 原型链中。hasOwnProperty() 只会查看属性是否在某个对象中,不会查看 [[prototype]] 原型链。
  5. 看起来 in 操作符能够查看容器内是否有某个值,然而它实际上查看的是某个属性名是否存在。对于数组来说这个区别十分重要,4 in [2, 4, 6] 的后果并不是你期待的 True,因为 [2, 4, 6] 这个数组中蕴含的属性名是 0、1、2,没有 4。
  6. propertyIsEnumerable(...) 会查看给定的属性名是否存在于对象中,而不是原型链中,并且满足 enumerable: true;
  7. Object.keys(...) 会返回一个数组,蕴含所有可枚举属性,Object.getOwnPropertyNames(...)会返回一个数组,蕴含所有属性,无论他们是否可枚举。
  8. in 与 hasOwnProperty(...) 的区别在于是否查找 [[prototype]] 原型链,而 Object.keys(...)、Object.getOwnPropertyNames(...)、propertyIsEnumerable(...)、hasOwnProperty() 都只会查找对象中是否间接蕴含某个属性。

小结

  1. 对象一共有两种语法:定义 (文字) 模式和结构模式。

    // 对象的文字语法大略是这样:var myObj = {
        key: value
        // ...
    };
    
    // 结构模式大略是这样:var myObj = new Object();
    myObj.key = value;
  2. 结构模式和文字模式生成的对象是一样的,惟一的区别在于,在文字申明中你能够增加多个键值对,但在结构模式中你必须一一增加属性。
  3. 在 JavaScript 中,为什么 typeof null 会返回 object?

    -   因为不同的对象在底层都示意为二进制,在 JavaScript 中二进制前三位都是 0 的话会被判断为 object 类型,null 的二进制示意是全 0,天然前三位也是 0,所以执行 typeof 时会返回 object。
  4. 对象中属性拜访的形式:

    var myObject = {a: 2};
    
    myObject.a; // 2
    
    myObject["a"]; // 2
  5. 上述形式中,应用 . 操作符被称为属性拜访,[] 操作符被称为键拜访。
  6. 禁止扩大: 若想禁止一个对象增加新属性并且保留已有属性,可应用 Object.preventExtensions(…)“

    -   ` 非严格模式下,创立属性 b 会静默失败。在严格模式下,将会抛出 TypeError 谬误。`
  7. 密封:Object.seal(..) 会创立一个“密封”的对象,这个办法实际上会在一个现有对象上调用。Object.preventExtensions(..) 并把所有现有属性标记为 configurable:false。
  8. 解冻:Object.freeze(..) 会创立一个解冻对象,这个办法实际上会在一个现有对象上调用 Object.seal(..) 并把所有“数据拜访”属性标记为 writable:false,这样就无奈批改它们的值。
  9. in 操作符会查看属性是否在对象及其[[prototype]] 原型链中。hasOwnProperty() 只会查看属性是否在某个对象中,不会查看 [[prototype]] 原型链。
  10. propertyIsEnumerable(...) 会查看给定的属性名是否存在于对象中,而不是原型链中,并且满足 enumerable: true;
  11. Object.keys(...) 会返回一个数组,蕴含所有可枚举属性,Object.getOwnPropertyNames(...)会返回一个数组,蕴含所有属性,无论他们是否可枚举。
  12. in 与 hasOwnProperty(...) 的区别在于是否查找 [[prototype]] 原型链,而 Object.keys(...)、Object.getOwnPropertyNames(...)、propertyIsEnumerable(...)、hasOwnProperty() 都只会查找对象中是否间接蕴含某个属性。

特殊字符形容:

  1. 问题标注 Q:(question)
  2. 答案标注 R:(result)
  3. 注意事项规范:A:(attention matters)
  4. 详情形容标注:D:(detail info)
  5. 总结标注:S:(summary)
  6. 剖析标注:Ana:(analysis)
  7. 提醒标注:T:(tips)

    往期举荐:

  8. 前端面试实录 HTML 篇
  9. 前端面试实录 CSS 篇
  10. JS 如何判断一个元素是否在可视区域内?
  11. Vue2、3 生命周期及作用?
  12. 排序算法:QuickSort
  13. 箭头函数与一般函数的区别?
  14. 这是你了解的 CSS 选择器权重吗?
  15. JS 中 call, apply, bind 概念、用法、区别及实现?
  16. 罕用位运算办法?
  17. Vue 数据监听 Object.definedProperty()办法的实现
  18. 为什么 0.1+ 0.2 != 0.3,如何让其相等?
  19. 聊聊对 this 的了解?
  20. JavaScript 为什么要进行变量晋升,它导致了什么问题?

    最初:

  21. 欢送关注『前端进阶圈』公众号,一起摸索学习前端技术 ……
  22. 公众号回复 加群 或 扫码, 即可退出前端交流学习群,一起高兴摸鱼和学习 ……
  23. 公众号回复 加好友,即可添加为好友

正文完
 0