ES6 对象及拓展

作者: 生命里那束光 | 来源:发表于2022-05-16 08:22 被阅读0次

一、对象与类

对象(object)是 JavaScript 最重要的数据结构

是一种数据类型,是具有相同特性(数据元素)和行为(功能)的对象的抽象。

1. 类和对象的区别
  • 类实例化的结果就是对象,类描述了一组有相同特性(属性)和相同行为的对象。
  • 类是对象的模板
//定义类
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    sayName() {
        console.log(this.name)
    }
}

let person1 = new Person("张三", 18);
person1.sayName();
let person2 = new Person("李四", 20);
2. 对象定义(声明)的两种方式

2.1 字面量的方式进行定义

var  obj = {
    name: "Tom ",
    sex: " man",
    age:19,
    run:function(){
        console.log("一天跑一公里");
    }
}

2.2 使用 new Object() 进行定义

var obj = new  Object();
//定义属性
obj.name = "Tom ";
obj.sex = " man";
obj.age = 19;
//定义方法
obj.run = function(){
    console.log("一天跑一公里");
}

二、创建对象的方式

1. 工厂模式
  • 使用简单的函数创建对象,为对象添加属性和方法,然后返回对象
// Class 模板
    function  Person(name,sex,age){
        var  obj = {};
        obj.name = name;
        obj.sex = sex;
        obj.age = age;
        obj.run = function(){
            console.log("每天坚持跑步");
        }
        return obj;
    }
    // 实例化
    var  person1 = Person("Tom","sex",19);
    //操作
    person1.run();  //  输出结果:每天坚持跑步

工厂模式的优缺点:

优点:
1、 在工厂模式中,用户只需要知道所要生产的具体东西,无须关心具体的创建过程,甚至不需要具体产品类的类名。
2、 在系统增加新的产品时,我们只需要添加一个具体产品类和对应的实现工厂,无需对原工厂进行任何修改,很好地符合了“开闭原则”。
缺点:
1、 每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

2. 构造函数模式(new)
  • 创建自定义引用类型,可以像创建内置对象实例一样使用new操作符,这种方法的缺点是,构造函数的每个成员都无法复用,每次创建出的对象都只有私有变量和私有方法,不能实现共用
//构造函数(这里就创建了一个Class模板)
    function Person(name,sex,age){
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.run = function(){
            console.log("每天坚持跑步");
        }
    }
 // 实例化 ( new Object())
    var person1 = new Person("Tom","man",19);
 //操作
    person1.run();// 每天坚持跑步


//改造构造函数,把方法抽出来,定义成公共方法
// 构造全局的对象
var  action = {
    run:function(){
        console.log("每天坚持跑步");
    }
}
//构造函数
function Person(name,sex,age){
    ...
    this.run = action.run;
}
//实例化
var person1 = new Person("Tom","man",19);
person1.run();

使用new操作符实例化类时,相当于使用new调用其的构造函数。构造流程图如下:

  1. 创建一个空对象,作为将要返回的对象实例。
  2. 将这个空对象的原型,指向构造函数的prototype属性。
  3. 将这个空对象赋值给函数内部的this关键字。
  4. 开始执行构造函数内部的代码。(完成赋值等操作)
  5. 最后返回这个对象。
3. 原型模式
  • 使用构造函数的prototype属性来指定共享的属性和方法,即使用构造函数定义实例属性,使用原型定义共享的属性和方法
//构造函数
function Person(name,sex,age){
    this.name = name;
    this.sex = sex;
    this.age = age;
}
//使用原型对象   Object.prototype
Person.prototype.run = function() {
    console.log("每天坚持跑步");
}
//实例化
var person1 = new  Person("Tom","man",19);
person1.run();//  每天坚持跑步

三、对象的方法

JS对象方法 作用
Object.defineProperty(obj, prop,descriptor) 定义/修改一个对象中的属性
Object.defineProperties(obj.props) 在一个对象上定义新的属性或修改现有属性,并返回该对象。
Object.getOwnPropertyDescriptor(obj,prop) 获取对象中的一个属性描述
Object.freeze(obj) 冻结一个对象,再也不能被修改
Object.isFrozen(obj) 返回布尔值,判断对象是否被冻结
Object.getOwnPropertyNames(obj) 返回指定对象所有属性,同时也包括不可枚举属性组成的数组(除了Symbol属性)
Object.getOwnPropertySymbols(obj) 返回一个给定对象自身的所有Symbol属性的数组
Object.isExtensible(obj) 判断对象是否具备可扩展性,返回布尔值
Object.create(obj,propertiesObject)**** 创建一个新对象,使用现有对象来提供新创建对象的proto
Object.isSealed(obj) 返回boolean, 判断对象是否为封闭对象
十九、Object.Seal(obj) 封闭一个对象,阻止添加新属性并将所有现有属性标记为不可配置
ES6新增的对象方法
Object.is(Value1 , Value2) 判断两个值是否为"相同的值"
Object.assign(target, source1, source2) 用于对象合并,将源对象(source)所有可枚举属性,复制到目标对象(target)
Object.getOwnPropertyDescriptors(obj) 获取目标对象中的所有属性描述
Object.setPrototypeOf(obj,property) 设置一个指定的对象的原型对象
Object.getPrototypeOf(obj) 返回指定对象的原型对象
Object.keys(obj) 获取一个对象中所有的键名key (除了不可枚举属性和Symbol属性)
Object.values(obj) 获取一个对象中所有的键值value(除了不可枚举属性和Symbol属性)
Object.entries(obj) 获取一个对象中所有的键值对(key和value)
Object.fromEntries(obj) 用于将一个键值对数组转为对象

四、判断对象类型

1. typeof
  • typeof 常用来判断基本数据类型,无法做到准确的判断对象类型,返回值字符串
function sum(a,b){
  return a+b
}
var symbol1 = Symbol("a")

console.log(typeof 42); // "number"
console.log(typeof NaN); // "number"
console.log(typeof Infinity); // "number"

console.log(typeof new String(1)); // "object"
console.log(typeof new Number(1)); //"object"

console.log(typeof String(1)); // "string"
console.log(typeof Number(1)); //"number"

console.log(typeof 'string'); //"string"
console.log(typeof true);//"boolean"
console.log(typeof sum); //"function"
console.log(typeof symbol1);// "symbol"
console.log(typeof null); //"object"
console.log(typeof undefined); // "undefined"

console.log(typeof Array); 
console.log(typeof Date);
console.log(typeof Object);

console.log(typeof new Array()); 
console.log(typeof new Date());
console.log(typeof Object());

console.log(typeof Bigint);
2. instanceof
  • ES6新增,为了解决typeof 无法检查出具体对象类型,返回布尔值
  • instanceof的本质:检测构造函数(右边)的 prototype 属性是否出现在某个实例对象(左边)的原型链上
// 检查是否属于某个构造函数
function A() {
  return "A"
}
var a = new A();
console.log(a instanceof A) // true

var b = {};
console.log(b instanceof Object); //true
var c = [];
console.log(c instanceof Object); //true
console.log(c instanceof Array); //true
console.log( ({a:1}) instanceof Object) // true

let obj = Object.create(null)
console.log(obj instanceof Object) // false
// Object.create(null) 例外
//[].proto 原型是指向Array.prototype的,说明两个对象是属于同一条原型链的,返回true
3. constructor
  • 通过constructor来判断数据的类型,但是除了null、undefined,因为他们不是由对象构建。
{1:"1"}.__proto__.contructor === Object; //true
1.__proto__.contructor === Number; // true
[1].__proto__.contructor === Array; // true
4.Object.prototype.toString.call()
  • 通过Object.prototype.toString返回对象类型字符串,判断类型
  • 建议:加上call() 改变this指向,因为如果在原型上定义了toString方法,this的指向会指向为原型定义的方法,可能达不到预期目的
Object.prototype.toString.call('1') // [object String]
Object.prototype.toString.call(1) // [object Number]
Object.prototype.toString.call([1]) // [object Array]
Object.prototype.toString.call(true) // [object Boolean]
Object.prototype.toString.call(undefined) // [object Undefined]
Object.prototype.toString.call(null) // [object Null]

Object.prototype.toString.call(new Array()); // [object Array]
Object.prototype.toString.call(new Function()); // [object Function]
Object.prototype.toString.call(new Date()); // [object Date]
Object.prototype.toString.call(new Object()); // [object Object]
Object.prototype.toString.call(new RegExp()); // [object RegExp]
Object.prototype.toString.call(new Error()); // [object Error]

五、ES6对象新特性

1. 属性的简洁表示法

ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。

  • 如果对象的属性值和属性如果发生重名,我们只写一个属性名即可,他会根据相同的属性名来获取相应的属性值;
  • 方法也可以简写。
let birth = '2000/01/01';

const Person = { //大括号里面,直接写入变量和函数,作为对象的属性和方法
  name: '张三',
  //等同于birth: birth
  birth,
  // 等同于hello: function ()...
  hello() { console.log('我的名字是', this.name); }
};

2. 属性名表达式

// 方法一  用标识符作为属性名,ES5,ES6使用字面量方式定义对象可用
obj.foo = true;
// 方法二  用表达式作为属性名,ES6使用字面量方式定义对象可用
obj['a' + 'bc'] = 123;

3. 方法的 name 属性

  • 对象中方法函数里面name隐式属性的值就是方法名
const person = {
  sayName() {
    //隐式属性name:"sayName"
    console.log('hello!');
  },
};

person.sayName.name   // "sayName"

4. 属性的可枚举性和遍历

可枚举性:对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象。

属性的遍历:

遍历对象属性的方法 区别
for...in 循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)
Object.keys(obj) 返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名
Object.getOwnPropertyNames(obj) 返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名
Object.getOwnPropertySymbols(obj) 返回一个数组,包含对象自身的所有 Symbol 属性的键名
Reflect.ownKeys(obj) 返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举

5. super 关键字(做对象使用)

  • ES6 又新增了另一个类似的关键字super指向当前对象的原型对象

  • super()的另一种使用场景:作为函数使用,子类必须在constructor方法中调用super方法,继承父类的属性和方法

6. 对象的扩展运算符

  • 扩展运算符是三个点(...),将一个数组转为用逗号分隔的参数序列。
console.log(...[1, 2, 3])
// 1 2 3

console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5

[...document.querySelectorAll('div')]
// [<div>, <div>, <div>]

7. AggregateError 错误对象

  1. AggregateError 在一个错误对象里面,封装了多个错误。如果某个单一操作,同时引发了多个错误,需要同时抛出这些错误,那么就可以抛出一个 AggregateError 错误对象,把各种错误都放在这个对象里面。

  2. AggregateError 本身是一个构造函数,用来生成 AggregateError 实例对象。

  1. AggregateError(errors[, message])的实例对象有三个属性。

    • name:错误名称,默认为“AggregateError”。

    • message:错误的提示信息。

    • errors:数组,每个成员都是一个错误对象。

相关文章

  • ES6 对象及拓展

    一、对象与类 对象(object)是 JavaScript 最重要的数据结构。类是一种数据类型,是具有相同特性(数...

  • JavaScript OOP篇

    参考资料 JavaScript面向对象简介 ES6对象的拓展 ES6 class 前言 本篇主要介绍 JavaSc...

  • 扩展对象的功能性.md

    对象扩展 对象类别 在ES6中,对象分为下面几种叫法。 普通对象 特异对象 标准对象 内建对象 对象字面量语法拓展...

  • es6之对象拓展

    本文目录: 1.对象简写 2.属性名表达式 3.扩展运算符 4.Object新增方法 1.对象简写 在es5中,有...

  • ES6 函数及拓展

    一、函数 函数是一个为执行特定任务而设计,可以重复使用的代码块。 1. 创建函数的三种方式 函数声明方式:func...

  • ES6方向:对象扩展

    1、对象 1、对象的书写形式 1.2、属性名表达式 定义对象的属性,有两种方式 在ES6中拓展了ES5的缺陷,在使...

  • ES5、ES6对象合并方法大全

    ES5:循环遍历 ES6:object.assign ES6:拓展运算

  • 项目开发中 常用es6--API【必会之对象的拓展符】人送外号

    es6中的三个点到底是用来做什么的?到底是龙是马拉出来溜溜。。。 对象的拓展运算符拓展运算符(...)用于取出参数...

  • ES6 数组拓展、对象拓展、函数、类的语法

    一、数组的拓展 二、对象的拓展 三、函数的拓展 四、class基本语法

  • ES6对象的拓展

    在es6的语法中,我们可以使用新的对象方法: Object.is(); 判断两个值是否相等。 它与数值判断===恒...

网友评论

    本文标题:ES6 对象及拓展

    本文链接:https://www.haomeiwen.com/subject/kjnlurtx.html