理论+实践:从原型链到继承模式,掌握 Object 的精髓(一)

简介: 理论+实践:从原型链到继承模式,掌握 Object 的精髓(一)

理论+实践:从原型链到继承模式,掌握 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

不变性

  1. 1. 对象常量:结合 writable: false 和 configurable: false 即可创建一个真正的常量属性。(不可修改,重定义或删除)
var myObject = {};
Object.defineProperty( myObject, "FAVORITE_NUMBER", {
    value: 42,
    writable: false,
    configurable: false
} );
  1. 1. 禁止扩展: 若想禁止一个对象添加新属性并且保留已有属性,可使用 Object.preventExtensions(...)``
  • 非严格模式下,创建属性 b 会静默失败。在严格模式下,将会抛出 TypeError 错误。
var myObject = {
    a:2
};
Object.preventExtensions( myObject );
myObject.b = 3;
myObject.b; // undefined
  1. 1. 密封:Object.seal(..) 会创建一个“密封”的对象,这个方法实际上会在一个现有对象上调用。Object.preventExtensions(..) 会把所有现有属性标记为 configurable:false。
  • • 故密封之后不仅不能添加新属性,也不能重新配置或删除现有属性(虽然可修改属性的值)。`
  1. 2. 冻结:Object.freeze(..) 会创建一个冻结对象,这个方法实际上会在一个现有对象上调用Object.seal(..) 并把所有“数据访问”属性标记为 writable:false,这样就无法修改它们的值。

存在性

  • • 在属性中属性返回可能是 undefined。但有可能属性中有可能储存的就是 undefined, 也有可能是因为属性不存在就返回 undefined。那如何区分呢?
  • 可在不访问属性值的情况下判断对象中是否存在这个属性:
var myObject = {
    a:2
};
("a" in myObject); // true
("b" in myObject); // false
myObject.hasOwnProperty( "a" ); // true
myObject.hasOwnProperty( "b" ); // false
  • in 操作符会检查属性是否在对象及其[[prototype]] 原型链中。hasOwnProperty() 只会检查属性是否在某个对象中,不会检查 [[prototype]] 原型链。
  • • 看起来 in 操作符可以检查容器内是否有某个值,但是它实际上检查的是某个属性名是否存在。对于数组来说这个区别非常重要,4 in [2, 4, 6] 的结果并不是你期待的 True,因为 [2, 4, 6] 这个数组中包含的属性名是 0、1、2,没有 4。
  • propertyIsEnumerable(...) 会检查给定的属性名是否存在于对象中,而不是原型链中,并且满足 enumerable: true;
  • Object.keys(...) 会返回一个数组,包含所有可枚举属性,Object.getOwnPropertyNames(...)会返回一个数组,包含所有属性,无论他们是否可枚举。
  • in 与 hasOwnProperty(...) 的区别在于是否查找 [[prototype]] 原型链,而 Object.keys(...)、Object.getOwnPropertyNames(...)、propertyIsEnumerable(...)、hasOwnProperty() 都只会查找对象中是否直接包含某个属性。

小结

  1. 1. 对象一共有两种语法:`定义(文字)形式和构造形式。`
// 对象的文字语法大概是这样:
var myObj = {
    key: value
    // ...
};
// 构造形式大概是这样:
var myObj = new Object();
myObj.key = value;
  • 构造形式和文字形式生成的对象是一样的,唯一的区别在于,在文字声明中你可以添加多个键值对,但在构造形式中你必须逐个添加属性。
  1. 1. 在 JavaScript 中,为什么 typeof null 会返回 object?- 因为不同的对象在底层都表示为二进制,在 JavaScript 中二进制前三位都是 0 的话会被判断为 object 类型,null 的二进制表示是全 0,自然前三位也是 0,所以执行 typeof 时会返回 object。
  2. 2. 对象中属性访问的方式:
var myObject = {
    a: 2
};
myObject.a; // 2
myObject["a"]; // 2
  • • 上述方式中,使用 . 操作符被称为属性访问, [] 操作符被称为键访问。
  1. 1. 禁止扩展: 若想禁止一个对象添加新属性并且保留已有属性,可使用 Object.preventExtensions(...)``
  • 非严格模式下,创建属性 b 会静默失败。在严格模式下,将会抛出 TypeError 错误。
  1. 2. 密封:Object.seal(..) 会创建一个“密封”的对象,这个方法实际上会在一个现有对象上调用。Object.preventExtensions(..) 并把所有现有属性标记为 configurable:false。
  2. 3. 冻结:Object.freeze(..) 会创建一个冻结对象,这个方法实际上会在一个现有对象上调用Object.seal(..) 并把所有“数据访问”属性标记为 writable:false,这样就无法修改它们的值。
  3. 4. in 操作符会检查属性是否在对象及其[[prototype]] 原型链中。hasOwnProperty() 只会检查属性是否在某个对象中,不会检查 [[prototype]] 原型链。
  4. 5. propertyIsEnumerable(...) 会检查给定的属性名是否存在于对象中,而不是原型链中,并且满足 enumerable: true;
  5. 6. Object.keys(...) 会返回一个数组,包含所有可枚举属性,Object.getOwnPropertyNames(...)会返回一个数组,包含所有属性,无论他们是否可枚举。
  6. 7. in 与 hasOwnProperty(...) 的区别在于是否查找 [[prototype]] 原型链,而 Object.keys(...)、Object.getOwnPropertyNames(...)、propertyIsEnumerable(...)、hasOwnProperty() 都只会查找对象中是否直接包含某个属性。

特殊字符描述

问题标注 Q:(question)答案标注 R:(result)注意事项标准:A:(attention matters)详情描述标注:D:(detail info)总结标注:S:(summary)分析标注:Ana:(analysis)提示标注:T:(tips)

相关文章
|
7月前
|
设计模式 Java 测试技术
软件测试/测试开发/全日制|Page Object模式:为什么它是Web自动化测试的必备工具
软件测试/测试开发/全日制|Page Object模式:为什么它是Web自动化测试的必备工具
网易:所有的对象最终都会继承自 Object.prototype ? ——原型链(二)详细讲解!
网易:所有的对象最终都会继承自 Object.prototype ? ——原型链(二)详细讲解!
|
4月前
|
JavaScript
网易:所有的对象最终都会继承自 Object.prototype ? ——原型链(一)详细讲解!
网易:所有的对象最终都会继承自 Object.prototype ? ——原型链(一)详细讲解!
|
6月前
|
Java 编译器 数据处理
JavaSE——面相对象高级一(4/4)-继承相关的注意事项:权限修饰符、单继承、Object类、方法重写、子类访问成员的特点......
JavaSE——面相对象高级一(4/4)-继承相关的注意事项:权限修饰符、单继承、Object类、方法重写、子类访问成员的特点......
64 0
|
7月前
|
Java 流计算
在Flink实时任务中,POJO(Plain Old Java Object)对象的模式演进可能会引起不兼容的问题
【2月更文挑战第6天】在Flink实时任务中,POJO(Plain Old Java Object)对象的模式演进可能会引起不兼容的问题
90 3
理论+实践:从原型链到继承模式,掌握 Object 的精髓(二)(下)
理论+实践:从原型链到继承模式,掌握 Object 的精髓(二)(下)
|
存储 JavaScript 前端开发
理论+实践:从原型链到继承模式,掌握 Object 的精髓(二)(上)
理论+实践:从原型链到继承模式,掌握 Object 的精髓(二)
|
7天前
|
JSON Java Apache
Java基础-常用API-Object类
继承是面向对象编程的重要特性,允许从已有类派生新类。Java采用单继承机制,默认所有类继承自Object类。Object类提供了多个常用方法,如`clone()`用于复制对象,`equals()`判断对象是否相等,`hashCode()`计算哈希码,`toString()`返回对象的字符串表示,`wait()`、`notify()`和`notifyAll()`用于线程同步,`finalize()`在对象被垃圾回收时调用。掌握这些方法有助于更好地理解和使用Java中的对象行为。
|
1月前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
135 4
|
2月前
|
Java
Java Object 类详解
在 Java 中,`Object` 类是所有类的根类,每个 Java 类都直接或间接继承自 `Object`。作为所有类的超类,`Object` 定义了若干基本方法,如 `equals`、`hashCode`、`toString` 等,这些方法在所有对象中均可使用。通过重写这些方法,可以实现基于内容的比较、生成有意义的字符串表示以及确保哈希码的一致性。此外,`Object` 还提供了 `clone`、`getClass`、`notify`、`notifyAll` 和 `wait` 等方法,支持对象克隆、反射机制及线程同步。理解和重写这些方法有助于提升 Java 代码的可读性和可维护性。
115 20