常用Object的方法

object.is() ===

方法用来判断两个值是否相等,它接收两个参数,分别是需要比较的两个值。Object.is中的NaN与NaN是相等的。 同时Object.is也不会强制转换两边的值的类型,Object.is与===的区别主要体现在+0和-0以及对NaN的比较上。

javascript 复制代码
    console.log(+0 === -0);            //true
    console.log(NaN === NaN)           //false
    console.log(NaN == NaN);          //false
    console.log(Object.is(+0, -0));   //false
    console.log(Object.is(NaN, NaN))  //true


 == 比较两个值是否相等,如果两边的值不是同一个类型的话,会将他们转为同一个类型后再进行比较。
     123 == '123';   // true
     '' == false;    // true
     false == 0;     // true
     NaN == NaN;     // false


    === 不会对类型进行转换,两边的值必须相等且类型相同才会等到 true 。
     123 === 123;     // true
     123 === '123';   // false
     '' === false;    // false
     false === 0;     // false
     NaN === NaN;     // false


    需要特殊注意的是,对于 0 和 NaN 的比较。无论 0 的正负,他们都是相等的,而 NaN 是与任何值都不相等的,包括他本身。
     + 0 === -0;        // true
     0 === -0;          // true
     +0 === 0;          // true
     NaN === NaN;       // false

Object.assign()

Object.assign()方法用于将一个或多个源对象的可枚举属性复制到目标对象中,并返回目标对象。它基于浅复制原则,只复制对象自身的属性,不复制继承自原型链上的属性。如果目标对象已经存在相同属性,则源对象的属性将覆盖目标对象的属性。

语法:

Object.assign(target, ...sources)

`target`:目标对象,要将属性复制到的对象。

`sources`:一个或多个源对象,从中复制属性的对象。

情况一:如果后面对象的属性,比如source中存在属性b,而目标对象(第一个参数)中也存在属性b,则source里的属性b值,会覆盖前面的属性b值 复制对象,存在相同key,则后面覆盖前面的

javascript 复制代码
     const target = { a: 1, b: 2 };
     const source = { b: 4, c: 5 };
     const result = Object.assign(target, source);
     console.log(result); //{a:1,b:4,c:5}

情况二:Object.assign() 会改变第一个对象的值,后面对象的值不会改变,遇到相同key,后面的值会覆盖前面的

javascript 复制代码
     const target1 = { a: 1, b: 2 };
     const source1 = { b: 4, c: 5, d: 6 };
     Object.assign(target1, source1);
     console.log(target1);  //{a:1,b:4,c:5,d:6}
     console.log(source1);  // { b: 4, c: 5, d: 6 }

情况三:如果想合并几个对象生成新的对象,并对原来的对象内容无影响,可以将Object.assign()的第一个参数设为空对象

javascript 复制代码
     const obj1 = { a: 1, b: 2 };
     const obj2 = { b: 4, c: 5 };
     const obj3 = { d: 6 };
     const merged = Object.assign({}, obj1, obj2, obj3);
     console.log(merged); // { a: 1, b: 4, c: 5, d: 6 }

注意事项

Object.assign()方法不会拷贝对象的不可枚举属性、原型链属性以及方法。

当源对象含有getter时,会触发getter的执行。

Object.assign()是浅复制,所以在处理嵌套对象时需要小心。

Object.entries()

方法返回一个给定对象自身可枚举属性的键值对数组。其排列与使用 for...in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)

当参数为对象时

javascript 复制代码
     const obj = { name: 'xiaoming', age: 'seven', sex: 'man', grade: 'four' };
     const res = Object.entries(obj)
     console.log(res);
     //[
    //     ['name', 'xiaoming'],
    //     ['age', 'seven'],
    //     ['sex', 'man'],
    //     ['grade', 'four']
    // ]

当参数为数组时

javascript 复制代码
     const obj = [1, 2, 3, 4, 5, 6]
     const res = Object.entries(obj)
     console.log(res);
    // [
    //     ['0', 1],
    //     ['1', 2],
    //     ['2', 3],
    //     ['3', 4],
    //     ['4', 5],
    //     ['5', 6]
    // ]

参数为数组(数组中包含对象)

javascript 复制代码
     const obj = [1, 2, 3, 4, 5, 6, { a: 'a' }, { b: 'b' }, { c: 'c' }]
     const res = Object.entries(obj)
     console.log(res);

参数为数组(数组中元素为对象)

javascript 复制代码
     const obj = [{ a: 'a' }, { b: 'b' }, { c: 'c' }]
    const res = Object.entries(obj)
    console.log(res);

Object转换为Map

javascript 复制代码
      const obj = { name: 'xiaoming', age: 'seven', sex: 'man', grade: 'four' };
      console.log(Object.entries(obj));
      const map = new Map(Object.entries(obj));
      console.log(map);

Object.values()

官方定义 返回一个给定对象的自有可枚举字符串键属性值组成的数组

javascript 复制代码
     const object1 = {
      a: 'somestring',
       b: 42,
       c: false,
     };
     console.log(Object.values(object1));// ['somestring', 42, false]



    var obj2 = {
       gtq: {name: '光头强',age: '18',height: '177'},
       xd: {name: '熊大',age: '12',height: '190'},
       xe: {name: '熊二',age: '10',height: '188'}
     }
     const list2 = Object.values(obj2);
     console.log(list2)
    // 得到:
    /**
     *  [
     *    {name: '光头强', age: '18', height: '177'},
     *    {name: '熊大', age: '12', height: '190'},
     *    {name: '熊二', age: '10', height: '188'}
     *  ]
     *
    */

Object.defineProperty()

该方法允许精确添加或修改对象的属性。通过赋值操作添加的普通属性是可枚举的,能够在属性枚举期间呈现出来(for...in 或 Object.keys 方法), 这些属性的值可以被改变,也可以被删除。方法Object.defineProperty()允许修改默认的属性元数据配置。我们可以认为Object.defineProperty()定义的属性在使用上更加严格。

语法:Object.defineProperty(obj, prop, descriptor)

obj 要在其上定义属性的对象。

prop String|Symbol,Required,要定义或修改的属性的名称。

descriptor Object,Required,将被定义或修改的属性描述符。

参数descriptor就是属性描述符,就是定义属性行为的元数据信息。属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个Boolean类型的元数据属性,值为true或false,用于定义对属性的某种操作行为是允许还是禁止。存取描述符是由getter-setter函数对描述的属性。描述符必须是这两种形式之一,即descriptor要么是数据描述符,要么是存取描述符,不能同时包含数据描述符和存取描述符。

configurable

当且仅当该属性的 configurable 为 true 时,才能够再次修改该属性的属性描述符,同时该属性也能从对应的对象上被删除。默认为 false。

enumerable

当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中。默认为 false。数据描述符除了具有configurable和enumerable这两个元数据键值外,还具有以下可选键值:

value

该属性的初始值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。

writable

当且仅当该属性的writable为true时,该属性才能被写入值。默认为 false。

存取描述符除了具有configurable和enumerable这两个元数据键值外,还具有以下可选键值:

get

一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。默认为 undefined。

set

一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。默认为 undefined。

|-------|--------------|------------|-------|----------|-----|-----|
| | configurable | enumerable | value | writable | get | set |
| 数据描述符 | Yes | yes | yes | yes | no | no |
| 存取描述符 | yes | yes | no | no | yes | yes |

javascript 复制代码
// 如果一个描述符不具有value,writable,get 和 set 任意一个关键字,那么它将被认为是一个数据描述符。如果一个描述符同时有(value或writable)和(get或set)关键字,将会产生一个异常。
   // 向对象中添加一个属性并设置数据描述符
    const obj1 = {};
    Object.defineProperty(obj1, 'a', {
        value: 1,
        writable: true,
        enumerable: true,
        configurable: true
    })
    console.log(obj1.a)
    //向对象中添加一个属性并设置存取描述符
    const obj1={};
    var bValue;
    Object.defineProperty(obj1,'b',{
        get:function(){
            return bValue;
        },
        set:function (newValue){
            bValue=newValue;
        },
        enumerable:true,
        configurable:true
    })
    obj1.b=2;
    console.log(obj1.b)   输出: 2,表示属性b的getter和setter均生效
    //数据描述符和存取描述符不能混合使用
      const obj1={};
    抛出异常: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute
    Object.defineProperty(obj1, "c", {
    	value: 1,
    	get: function () {
        	return 2;
    	}
    });

    //当writable设置为false时(默认值即是false),该属性被定义为只读属性,即只能读取该属性值,不能给该属性写入值。
    const obj1 = {};
    Object.defineProperty(obj1, 'a', {
        value: 1,
        writable: true,
    })

    Object.defineProperty(obj1, 'b', {
        value: 2,
        writable: false,
    })
    obj1.a = 100; // 向属性a中写入值
    console.log(obj1.a); // 输出: 100,表示属性a的【writable: true】已生效

    // 严格模式下抛出异常 TypeError: Cannot assign to read only property 'b' of object '#<Object>'
    // 非严格模式不抛出异常,但是不生效
    obj1.b = 200; // 向属性b中写入值
    console.log(obj1.b); // 输出: 1

    //enumerable定义了对象的属性是否可以在 for...in 循环和 Object.keys() 中被枚举。
       const obj1={};
       Object.defineProperty(obj1,'a',{
        value:1,
        enumerable:true, // 用于定义属性a可以被枚举
       })
       Object.defineProperty('obj1','b',{
        value:2,
        enumerable:false   // 用于定义属性b不可以被枚举
       })
       for (let key in obj1){
        console.log(key);   //'a'
       }

       console.log(Object.keys(obj1));  //['a'];
       console.log('a' in obj1);  //true
       console.log('b' in obj1)    //true

      //get 和set
    //设置getter 和setter 的普通示例
    const obj = {};
    let v = null;
    Object.defineProperty(obj1, 'a', {
        get: function () {
            return v
        },
        set: function (newValue) {
            v = newValue
        }
    })
    obj1.a=1;
    console.log(obj1.a)  // 输出: 1,表示属性a的getter和setter均生效

    //继承属性
    function Person() {
        // 在Person的原型上定义属性name,并设置getter以及setter,这样Person类的示例均能访问name属性,且实例的name属性互相隔离
        Object.defineProperty(Person, 'name', {
            get: function () {
                return this._name;
            },
            set: function (newValue) {
                this._name = newValue;
            }
        })
    }
    const a = new Person();
    const b = new Person();
    a.name = '张三';
    b.name = 'lisi';
    console.log(a.name);  //张三
    console.log(b.name);  //lisi


    //configurable用于表示对象的属性是否可以被删除的示例
    'use strict';   //严格模式
    const obj1 = {};
    Object.defineProperty(obj1, 'a', {
        value: 1,
        configurable: true
    })
    Object.defineProperty(obj1, 'b', {
        value: 2,
        configurable: false
    });
    delete obj1.a    // 从对象obj1中删除属性a
    console.log(obj1.a)
    // 严格模式下抛出异常 TypeError: Cannot delete property 'b' of #<Object>
    // 非严格模式下不会抛出异常,但是不生效
    delete obj1.b; // 从对象obj2中删除属性b
    console.log(obj1.b); // 输出: 2,表示删除属性b失败


    //configurable值为false表示属性描述符不能被再次修改的示例
    'use strict';   //严格模式
    const obj1 = {};
    Object.defineProperty(obj1, 'a', {
        value: 1, // 用于定义a的默认值为1
        configurable: false,
        writable: false, // 将属性a定义为只读不可写
        enumerable: false // 将属性a定义为不可枚举
    })
    // 严格模式会抛出异常
    // 非严格模式不会抛出异常,但不生效
    obj1.a = 100;
    console.log(obj1.a); // 输出: 1
    console.log(Object.keys(obj1)); // 输出: []

    // 抛出异常TypeError: Cannot redefine property: a
    // 说明当上次对属性a调用Object.defineProperty()设置configurable为false后,a的属性描述符不能被再次修改,即不能再次对属性a调用Object.defineProperty()方法
    Object.defineProperty(obj1, 'a', {
        value: 2, // 用于定义a的默认值为1
        configurable: true,
        writable: true, // 重新将属性a定义为可写
        enumerable: true // 重新将属性a定义为可枚举
    });

   //由于上面抛出异常,以下代码均无法执行
    console.log(obj1.a);
    obj1.a = 200;
    console.log(obj1.a);
    console.log(Object.keys(obj1));


     //  configurable值为true表示属性描述符可以被再次修改的示例
    'use strict';
    const obj1 = {};
    Object.defineProperty(obj1, 'a', {
        value: 1, // 用于定义a的默认值为1
        configurable: true, // 表示可以对属性a再次调用Object.defineProperty()方法
        writable: false, // 将属性a定义为只读不可写
        enumerable: false // 将属性a定义为不可枚举
    });

    obj1.a = 100;
    console.log(obj1.a); // 输出: 1
    console.log(Object.keys(obj1)); // 输出: []

    Object.defineProperty(obj1, 'a', {
        value: 2, // 用于定义a的默认值为2
        configurable: true,
        writable: true, // 重新将属性a定义为可写
        enumerable: true // 重新将属性a定义为可枚举
    });

    console.log(obj1.a); // 输出: 2,表示【writable: true】生效

    obj1.a = 200;
    console.log(obj1.a); // 输出: 200,表示【writable: true】生效
    console.log(Object.keys(obj1)); // 输出: ['a'],表示【enumerable: true】生效

    let bValue = null;
    Object.defineProperty(obj1, 'b', {
        configurable: true, // 表示可以对属性a再次调用Object.defineProperty()方法
        get() {
            return bValue;
        },
        set(newValue) {
            bValue = newValue;
        }
    });

    obj1.b = 'abcd';
    console.log(obj1.b); // 输出: 'abcd'

    Object.defineProperty(obj1, 'b', {
        configurable: true, // 表示可以对属性a再次调用Object.defineProperty()方法
        get() {
            return bValue.toString().toUpperCase();
        },
        set(newValue) {
            bValue = newValue + '_' + newValue;
        }
    });

    obj1.b = 'efgh';

    console.log(obj1.b); // 输出: 'EFGH_EFGH',表示新的setter和getter已经生效

Object.create()

创建一个新对象,使用现有的对象来提供新创建的对象的__proto__

语法: Object.create(proto[, propertiesObject])

javascript 复制代码
  const person = {
        isHuman: false,
        printIntroduction: function () {
            console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
        }
    };

    const me = Object.create(person);
    console.log(me);


    const person = {
        isHuman: false,
        printIntroduction: function () {
            console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
        }
    };

    const me = Object.create(person);
    me.name = 'Matthew'; // name是me的属性不是person的
    me.isHuman = true; //  isHuman也是属性上
    me.printIntroduction();
    // "My name is Matthew. Am I human? true"
    console.log(me);

    // proto
    // 新创建对象的原型对象。
    // propertiesObject
    // 可选。如果没有指定为 undefind, 则是要添加到新创建对象的不可枚举
    // (默认)属性(即其自身定义的属性,而不是其原型链上的枚举属性)
    // 对象的属性描述符以及相应的属性名称。这些属性对应Object.defineProperties()
    // 的第二个参数。(可以点击去了解也是我写的)



    function Person(name, age) {
        this.name = name;
        this.age = age;
    }
    Person.prototype.getName = function () {
        return this.name
    }
    Person.prototype.getAge = function () {
        return this.age;
    }

    function Student(name, age, grade) {
        // 构造函数继承
        Person.call(this, name, age);
        this.grade = grade;
    }

    // 原型继承
    Student.prototype = Object.create(Person.prototype, {
        // 不要忘了重新指定构造函数 这个是必须的
        constructor: {
            value: Student
        },
        foo: {
            writable: true,
            configurable: true,
            value: "hello"
        },
        getGrade: {
            value: function () {
                return this.grade
            }
        }
    })


    var s1 = new Student('ming', 22, 5);
    console.log(s1.getName());  // ming
    console.log(s1.getAge());   // 22
    console.log(s1.getGrade()); // 5
    console.log(s1.foo); // hello
    //  Student 继承自Person,Person继承自Object
    console.log(s1 instanceof Student);
    console.log(s1 instanceof Person);
    console.log(s1 instanceof Object);
    // 结果 true true true


    function MyClass() {
        SuperClass.call(this);
        OtherSuperClass.call(this);
    }
    // 继承一个类
    MyClass.prototype = Object.create(SuperClass.prototype);
    // 混合其它
    Object.assign(MyClass.prototype, OtherSuperClass.prototype);
    // 重新指定constructor
    MyClass.prototype.constructor = MyClass;

    MyClass.prototype.myMethod = function () {
        // do a thing
    };


    // Object.assign 会把  OtherSuperClass原型上的函数拷贝到 MyClass原型上,
    // 使 MyClass 的所有实例都可用 OtherSuperClass 的方法

    
    var o;
    // 创建一个原型为null的空对象
    o = Object.create(null);
    o = {};
    // 以字面量方式创建的空对象就相当于:
    o = Object.create(Object.prototype);


    o = Object.create(Object.prototype, {
        // foo会成为所创建对象的数据属性
        foo: {
            writable: true,
            configurable: true,
            value: "hello"
        },
        // bar会成为所创建对象的访问器属性
        bar: {
            configurable: false,
            get: function () { return 10 },
            set: function (value) {
                console.log("Setting `o.bar` to", value);
            }
        }
    });


    function Constructor() { }
    o = new Constructor();
    // 上面的一句就相当于:
    o = Object.create(Constructor.prototype);
    // 当然,如果在Constructor函数中有一些初始化代码,Object.create不能执行那些代码


    // 创建一个以另一个空对象为原型,且拥有一个属性p的对象
    o = Object.create({}, { p: { value: 42 } })

    // 省略了的属性特性默认为false,所以属性p是不可写,不可枚举,不可配置的:
    o.p = 24
    o.p
    //42

    o.q = 12
    for (var prop in o) {
        console.log(prop)
    }
    //"q"

    delete o.p
    //false

    //创建一个可写的,可枚举的,可配置的属性p
    o2 = Object.create({}, {
        p: {
            value: 42,
            writable: true,
            enumerable: true,
            configurable: true
        }
    });
相关推荐
T^T尚3 小时前
uniapp H5上传图片前压缩
前端·javascript·uni-app
出逃日志3 小时前
JS的DOM操作和事件监听综合练习 (具备三种功能的轮播图案例)
开发语言·前端·javascript
XIE3924 小时前
如何开发一个脚手架
前端·javascript·git·npm·node.js·github
GISer_Jing4 小时前
React渲染相关内容——渲染流程API、Fragment、渲染相关底层API
javascript·react.js·ecmascript
山猪打不过家猪4 小时前
React(五)——useContecxt/Reducer/useCallback/useRef/React.memo/useMemo
前端·javascript·react.js
前端青山4 小时前
React事件处理机制详解
开发语言·前端·javascript·react.js
科技D人生4 小时前
Vue.js 学习总结(14)—— Vue3 为什么推荐使用 ref 而不是 reactive
前端·vue.js·vue ref·vue ref 响应式·vue reactive
对卦卦上心4 小时前
React-useEffect的使用
前端·javascript·react.js
练习两年半的工程师4 小时前
React的基本知识:事件监听器、Props和State的区分、改变state的方法、使用回调函数改变state、使用三元运算符改变state
前端·javascript·react.js
啵咿傲4 小时前
在React中实践一些软件设计思想 ✅
前端·react.js·前端框架