felix-cao / Blog

A little progress a day makes you a big success!
31 stars 4 forks source link

JavaScript 的 Object 对象 #43

Open felix-cao opened 6 years ago

felix-cao commented 6 years ago

一、面向对象

从设计模式上看,对象是计算机抽象现实世界的一种方式。面向对象编程(Object-Oriented Programming)的最主要目的是提高程序的重复使用性。

我们说,对象具有属性(property)和方法(function),(其实本质上方法也是一种属性)在面向对象的设计模式中,属性是一种描述,描述对象的状态,比如一个人一天 24 小时的情绪,每个时刻他的情绪都具有不同的状态,喜怒哀乐,抑郁癫狂,贪嗔痴念,当然情绪只是生而为人的众多状态中的一种而已。而对象中的方法是一种功能,它的功能就是操作对象的属性。比如,吃饭可以改变一个人的状态,对吃货而已,吃饱以后会觉得特别幸福,吃饭是一种功能,它改变了一个人的情绪,让人觉得幸福。

那么,反过来细想,人是一个对象,它具有情绪,他还要吃饭。所以可以说,对象是对属性和方法的一种封装。

在 JavaScript 里,同样认为“万物皆对象”,JavaScript 提供了一个 Object 对象,是 JavaScript 所有对象的基类, 即那些对象都是 Object 的实例对象,换句话说 JavaScript 中的所有对象都是由 Object 对象衍生的,本篇来聊一聊这个 Object 对象。

二、Object 函数作为工具方法使用

Object 本身是一个函数(理解这一点,请移步 JavaScript中函数的三种角色),可以当作工具方法使用,将任意值转为对象。这个方法常用于保证某个值一定是对象。如果参数为空(或者为 undefined 和 null ),Object() 返回一个空对象。

var obj = Object();
// 等同于
var obj = Object(undefined);
var obj = Object(null);

obj instanceof Object // true

上面代码的含义,是将 undefined 和 null 转为对象,结果得到了一个空对象 obj。 instanceof 运算符用来验证,一个对象是否为指定的构造函数的实例。obj instanceof Object 返回 true,就表示 obj 对象是 Object 的实例。 如果参数是原始类型的值,Object 方法将其转为对应的包装对象的实例。

var obj = Object(1);
obj instanceof Object // true
obj instanceof Number // true

var obj = Object('foo');
obj instanceof Object // true
obj instanceof String // true

var obj = Object(true);
obj instanceof Object // true
obj instanceof Boolean // true

上面代码中,Object 函数的参数是各种原始类型的值,转换成对象就是原始类型值对应的包装对象。 如果Object 方法的参数是一个对象,它总是返回该对象,即不用转换。

var arr = [];
var obj = Object(arr); // 返回原数组
obj === arr // true

var value = {};
var obj = Object(value) // 返回原对象
obj === value // true

var fn = function () {};
var obj = Object(fn); // 返回原函数
obj === fn // true

  利用这一点,可以写一个判断变量是否为对象的函数

function isObject(value) {
  return value === Object(value);
}

isObject([]) // true
isObject(true) // false

三、Object函数作为构造函数使用

Object 不仅可以当作工具函数使用,还可以当作构造函数使用,即前面可以使用 new 操作符。Object 构造函数的首要用途,是直接通过它来生成新对象。

Object 构造函数的用法与工具方法很相似,几乎一模一样。使用时,可以接受一个参数,如果该参数是一个对象,则直接返回这个对象;如果是一个原始类型的值,则返回该值对应的包装对象

var o1 = {a: 1};
var o2 = new Object(o1);
o1 === o2 // true

var obj = new Object(123);
obj instanceof Number // true

虽然用法相似,但是 Object(value)new Object(value) 两者的语义是不同的,Object(value) 表示将value 转成一个对象,new Object(value) 则表示生成一个值是为 value 的新对象。

四、遍历对象属性

Object.keys()Object.getOwnPropertyNames() 这两个方法都是用来遍历对象的属性的 Object.keys 方法的参数是一个对象,返回一个数组。该数组的成员都是 该对象自身的(而不是继承的) 所有属性名。

var obj = {
  p1: 123,
  p2: 456
};

Object.keys(obj) // ["p1", "p2"]

Object.getOwnPropertyNames 方法与 Object.keys 类似,也是接受一个对象作为参数,返回一个数组,包含了该对象自身的所有属性名。

var obj = {
  p1: 123,
  p2: 456
};

Object.getOwnPropertyNames(obj) // ["p1", "p2"]

五、Object.create

Object.create(prototype, descriptors)

Reference

felix-cao commented 2 years ago

Object 的 Static methods

对象本身拥有的方法,被称为静态方法(Static method),而定义在对象原型(prototype)上的方法被称为实例方法(Instance method)

const arr = [1, 2, 3];  // 数组实例

Array.isArray(arr);     // isArray 是Array工具函数的静态方法
arr.push(4);            // push 是实例方法

1、对象遍历

ID Methods Tips Note
1 Object.keys 返回对象自身所有可枚举字符串属性的数组 own enumerable string properties
2 Object.getOwnPropertyNames 返回对象自身所有可枚举和不可枚举的属性的数组 own enumerable properties
3 Object.values 返回对象自身所有可枚举属性的值的数组 own enumerable string properties
4 Object.entries 返回对象自身所有可枚举属性的 [key, value] 数组 own enumerable string properties
5 Object.fromEntries 是Object.entries()的逆操作,将一个键值对数组转为对象

2、对象属性

ID Methods Tips Note
6 Object.getOwnPropertyDescriptor 返回对象指定的属性的Descriptor
7 Object.getOwnPropertyDescriptors
8 Object.defineProperty 给对象添加一个属性并指定该属性的Descriptor
9 Object.defineProperties

Object.getOwnPropertyDescriptorObject.getOwnPropertyDescriptors 的区别

const person = {  age: 35, name: 'czf' };
console.log(Object.getOwnPropertyDescriptor(person, 'name'))
console.log(Object.getOwnPropertyDescriptors(person))

3、对象原型

ID Methods Tips Note
10 Object.create 返回一个新的对象,并指定原型对象和属性
11 Object.getPrototypeOf 获取对象的 Prototype 原型
12 Object.setPrototypeOf 设置对象的 Prototype 原型

4、对象状态控制

ID Methods Tips Note
13 Object.preventExtensions
15 Object.isExtensible
16 Object.seal
17 Object.isSealed
18 Object.freeze 冻结一个对象
19 Object.isFrozen 判断一个对象是否被冻结

Reference

Object static methods

felix-cao commented 2 years ago

in 属性归属检测运算符

instanceof 实例归属检测运算符

felix-cao commented 2 years ago

indexOf: String.prototype.indexOf() indexOf: Array.prototype.indexOf() valueOf: Object.prototype.valueOf() setPrototypeOf: Object.setPrototypeOf() getPrototypeOf: Object.getPrototypeOf()