2023-07-18

二十一 Object对象

Object对象,是所有JavaScript对象的超类(基类)。Object.prototype(Obecjt的原型)定义了Js对象的基本方法和属性。

  • new Object() :返回一个Object实例
  • new Object(value) :根据value的值,返回不同的对象(Number、Boolean、String)
  • 参数:value {number | bool | string} :一个数字、布尔值或者字符串
  • 返回值:{Number、Boolean、String} 返回一个转换后的对象
        var o = new Object(123);
        console.log(o); // => Number对象
        o = new Object(true);
        console.log(o); // => Boolean对象
        o = new Object('abc');
        console.log(o); // => String对象
  1. 继承

    • 创建一个临时对象,在临时对象的原型中存放获取到的对象;然后返回新对象
         function obj(o){
             function f(){};
             f.prototype = o;
             return new f();
         }
         
         //在这个函数中执行上面创建的obj函数
         function transfrom(child,parent){
             var new = obj(parent.prototype);
             prototype.constructor = child;
             child.prototype = new;          
         }
         
         function sup(name){
             this.name = name;
             this.color = ["red","blue","green"]
         }
         
         sup.prototype.sayName = function(){
             console.log(this.name)
         }
         
         function sub(name,age){
             sup.call(this,name)
         }
     
             transfrom(sub,sup);
             sub.prototype.sayAge = function(){
                 console.log(this.age)
             }
    
  2. Object.is()比较两个值是否相等

            console.log(Object.is('foo', 'foo'));//true
            console.log(Object.is({}, {}));//false
            console.log(Object.is(NaN, NaN));//true;
            console.log(Object.is([], []));//false
            console.log(Object.is('+0', '-0'));
    
  3. Object.assign()对象的合并

         var target = { a: 1 }
            var source1 = { b: 2 }
            var source2 = { c: 3 }
            Object.assign(target, source1, source2);
            console.log(target)//返回的是第一个写入的数组中
    
  4. JSON.parse()把字符串转对象 只能解析标准的JSON类型。

  5. JSON.stringify()把对象转字符串 按标准来解析(可以把不标准的JSON类型转为标准的)

  6. 实例属性

    • __proto__ :设置或返回对象的原型对象(IE中不支持此属性)
      • 赋值时,对象继承新原型的所有方法和属性,以及新原型的原型链中的所有方法和属性
      • 属性名称以两个下划线开始和结束
      • 对象的__proto__== 对象类的prototype
    // 1.自定义对象多层继承
         function People(name) {
             this.name = name;
         }
     
         function Student(age) {
             this.age = age;
         }
         Student.prototype = new People(); // 设置Student的原型为People对象
          
         var s = new Student(22);
         console.log(s.__proto__); // => People 对象
         console.log(Student.prototype); // => People 对象
         console.log(s.__proto__ == Student.prototype); // => true
     
         // 2.对象直接量
         var p = {}; // 等于new Object()
         console.log(p.__proto__ == Object.prototype); // => true
    
  7. prototype

    • 设置或返回对象类的原型对象
      • prototype为对象类的属性。proto是对象的属性。
      • Js内置对象(Array、Date等对象)都有一个只读的prototype属性。 可将属性和方法添加到原型中,但不能为内置对象分配其他原型。
      • 自定义对象的prototype属性可进行读写操作。
         var Student = function (name) {
             this.name = name;
         };
         // 给Student的原型添加一个sayHello方法
         Student.prototype.sayHello = function () {
             alert('Hello,' + this.name);
         }
         var st = new Student('张三'); // 初始化对象st
         console.log(st.name); // => 张三
         st.sayHello(); // 弹出:Hello,张三
    
  8. constructor

    • 表示创建此对象的构造函数
      • 设置或返回创建此对象的构造函数。
      • 若一个对象有多层继承,将返回最先调用的构造函数。
      • obj.constructor.prototype 可表示对象的原型。
         // 1.内置对象
         var str = 'abc';
         console.log(str.constructor); // => function String 构造函数
         var o = {};
         console.log(o.constructor); // => function Object 构造函数
     
         // 2.自定义对象多层继承 :constructor返回最先调用的构造函数
         function People(name) {
         this.name = name; // s对象初始化时,先调用People构造函数,再调用Student构造函数
             console.log('People调用');
         }
         function Student(age) {
             this.age = age;
             console.log('Student调用');
         }
         Student.prototype = new People(); // 设置Student的原型为People对象
          
         var s = new Student(22);
         console.log(s.constructor); // => function People 构造函数
    
  9. proto、prototype、constructor 的关系

    • 对象的proto 等于 类的prototype
    • 对象的constructor 等于类,所以obj.constructor.prototype 可表示对象的原型。
    var o = {};
    console.log(o.__proto__ === Object.prototype); // true :对象的__proto__等于类的prototype
    console.log(o.constructor === Object); // true :对象的constructor 等于 类
    console.log(o.constructor.prototype === Object.prototype); // true :o.constructor.prototype 可表示对象的原型。
    
  10. 实例方法

    • hasOwnProperty(propertyName) :判断对象是否拥有一个指定名称的实例属性(非继承)
    • 参数:propertyName {string} :属性名称。
    • 返回值:{bool} 判断对象是否拥有一个指定名称的本地定义(非继承)的属性;此方法不会检查对象原型链中的属性。
      • true :属性为对象的实例属性,非继承。
      • false :属性不为对象的实例属性。
    //示例 :
            // 1.Object对象
            var o = new Object();
            o.name = '自定义属性'; // 定义一个实例属性
    console.log(o.hasOwnProperty('name')); // => true:name属性为实例o自己定义的,而非继承
    console.log(o.hasOwnProperty('toString')); // => false:toString为继承属性
             
            // 2.自定义对象
            var Student = function (name) {
                this.name = name;
            };
            // 给Student的原型添加一个sayHello方法
            Student.prototype.sayHello = function () {
                alert('Hello,' + this.name);
            }
            // 给Student的原型添加一个age属性
            Student.prototype.age = '';
             
            var st = new Student('张三'); // 初始化对象st
    console.log(st.hasOwnProperty('name')); // => true :调用构造函数时,通过this.name附加到实例对象上
    console.log(st.hasOwnProperty('sayHello')); // => false :sayHello方法为原型上的成员
    console.log(st.hasOwnProperty('age')); // => false :age属性为原型上的成员
    
  11. isPrototypeOf(obejct) 判断某个原型是否出现在对象的原型链中

    • 语法:prototype.isPrototypeOf(object)
    • 参数:obejct {object} :被检测的对象。
    • 返回值:{bool} 返回某个原型是否出现在对象的原型链中
      • true :是
      • false :不是
    // 1.Obejct对象
            var o = new Object();
            console.log(Object.prototype.isPrototypeOf(o)); // => true :o为Obejct一个对象
             
            // 2.Array
            var array = [1, 2, 3];
            console.log(Array.prototype.isPrototypeOf(array)); // => true :数组原型
            console.log(Object.prototype.isPrototypeOf(array)); // => true :Object是所有对象的基原型
             
            // 3.自定义对象
            var People = function () {
            }
            var Student = function () {
            }
            // 设置Student类的原型为People
            Student.prototype = new People();
            var st = new Student();
            console.log(Student.prototype.isPrototypeOf(st)); // => true :st为Student一个对象
            console.log(People.prototype.isPrototypeOf(st)); // => true :Student的原型为People
            console.log(Object.prototype.isPrototypeOf(st)); // =>true :Object是所有对象的基原型
    
  12. propertyIsEnumerable(propertyName) :判断指定名称的属性是否为实例属性并且是可枚举的(可用for/in循环枚举)

    • 参数:propertyName {string} :属性名称
    • 返回值:{bool} 判断属性是否为实例属性并且是可枚举的(可用for/in循环枚举),不考虑原型链中的成员。
      • true :是
      • false :不是
    // 1.Array对象
            var array = [1, 2, 3];
            array.name = 'Array';
            console.log(array.propertyIsEnumerable('name')); // => true :name属性为实例属性
            console.log(array.propertyIsEnumerable('join')); // => false :join方法继承自Array
            console.log(array.propertyIsEnumerable('length')); // => false :length属性继承自Array
            console.log(array.propertyIsEnumerable('toString')); // => false :toString方法继承自Object
             
            // 2.自定义对象
            var Student = function (name) {
                this.name = name;
            }
            // 定义一个原型方法
            Student.prototype.sayHello = function () {
                alert('Hello' + this.name);
            };
            var a = new Student('tom');
            console.log(a.propertyIsEnumerable('name')); // => true :name为自身定义的实例属性
            console.log(a.propertyIsEnumerable('age')); // => false :age属性不存在,也返回false
            console.log(a.propertyIsEnumerable('sayHello')); // => false :sayHello属于原型方法
    
    
  13. toLocaleString() :返回当前对象的一个本地化的字符串表示

  14. toString() :返回当前对象的一个字符串表示形式

  15. valueOf() :返回当前对象的原始值

    • 参数:无
    • 返回值:{object} 返回当前对象关联的原始值,若没有相关联的值,则返回对象本身
            var a = [1, 2, 3];
            console.log(a.valueOf()); // => [1, 2, 3]
             
            var b = true;
            console.log(b.valueOf()); // => true
             
            var c = {};
            console.log(c.valueOf()); // => Object {}
             
            var s = 'abc';
            console.log(s.valueOf()); // => abc
             
            // 自定义个对象,重写valueOf
            var customObject = {};
            customObject.valueOf = function () {
                return '自定义对象';
            }
            console.log(customObject.valueOf()); // => 自定义对象
    
  16. 静态方法

    • Object.create(prototype, propertyDescriptor):创建并返回一个指定原型和指定属性的对象
    • 参数:
      • prototype {prototype} :返回对象的原型,可以为null。若为null,对象的原型为undefined。
      • propertyDescriptor {propertyDescriptor} 可选:属性描述符。
    //属性描述符:设置属性的一系列特性;
                
    语法格式:
    propertyName: {
        value: '', // 设置此属性的值
            writable: true, // 设置此属性是否可写入;默认为false:只读
                enumerable: true, // 设置此属性是否可枚举(通过for/in预付);默认为false:不可枚举
    configurable: true // 设置此属性是否可配置;如:是否可以修改属性的特性及删除属性。默认为false
                }
        
    //返回值:{object} 返回一个指定原型和指定属性的对象
    
            示例 :    
            // 建立个自定义对象,设置name和age属性
            var obj = Object.create(null, {
                name: {
                    value: 'tom',
                    writable: true,
                    enumerable: true,
                    configurable: true
                },
                age: {
                    value: 22
                }
            });
            console.log(obj.name); // => tom
            console.log(obj.age); // => 22
             
            obj.age = 28;
            console.log(obj.age); // => 22 :age属性的writable默认为false,此属性为只读
             
            for (p in obj) {
            console.log(p); // => name :只输出name属性;age属性的enumerable默认为false,不能通过for/in 枚举
            }
    
    • Object.defineProperties(object, propertyDescriptor) :添加/修改对象一个或多个属性的特性
    • 参数:
      • object {object} :对象
      • propertyDescriptor {propertyDescriptor} 属性描述符。
      • 若对象包含此属性,则是修改此属性的特性;否则为为对象添加此属性。
            var obj = {};
             
            // 为对象添加name和age属性
            Object.defineProperties(obj, {
                name: {
                    value: 'tom',
                    enumerable: true
                },
                age: {
                    value: 22,
                    enumerable: true
                }
            });
            for (p in obj) {
                console.log(p); // => name、age :输出name和age属性
            }
    
    • Object.defineProperty(obj, propertyName, propertyDescriptor) :添加/修改对象指定属性的特性
    • 参数:
      • object {object} :对象
      • propertyName {string} :属性的名称
      • propertyDescriptor {propertyDescriptor} 属性描述符。
      • 说明 :若对象包含此属性,则是修改此属性的特性;否则为添加此属性。
    //示例:
            var obj = {};
            // 添加一个name属性
            Object.defineProperty(obj, 'name', {
                    value: 'tom',
                    writable: true,
                    enumerable: true,
                    configurable:true
                }
            );
                    console.log(obj.name); // => tom :输出name属性的value的值
    
    • Object.freeze(object) :冻结对象,使其不能添加属性以及无法对现有的实例属性进行特性更改、值修改、属性删除等操作
    • 参数:
      • object {object} :对象
      • 说明 :此操作不可逆,冻结后无法进行解封。只影响实例属性,不影响原型属性。
            //示例:   
            var obj = {
                name: 'tom',
                age: 22
            };
            Object.freeze(obj); // 冻结对象
             
            obj.email = '123@qq.com';
            console.log(obj.email); // undefined :无法添加属性
            obj.age = 25;
            console.log(obj.age); // 22 :无法设置属性的值
    
    • Object.getOwnPropertyDescriptor(object, propertyName) :返回对象属性的描述符
    • 参数:
      • object {object} :对象
      • propertyName {propertyName} 属性名称
    • 返回值:
      • {propertyDescriptor} 属性描述符对象
    //示例 :          
            var obj = {
                name: 'tom',
                age: 22
            };
             
            var propertyDes = Object.getOwnPropertyDescriptor(obj, 'name');
            console.log(propertyDes); // => Object {value: "tom", writable: true, enumerable: true, configurable: true} :输出描述符对象
    
    
    • Object.getOwnPropertyNames(object) :返回一个数组,包含对象的所有实例属性和方法,不包含原型继承的属性和方法
    • 参数:
      • object {object} :对象
    • 返回值:
      • {Array} 一个数组,包含对象的所有实例属性和方法,不包含原型继承的属性和方法
    var obj = {
                name: 'tom',
                age: 22,
                sayHello: function () {
                    alert('Hello' + this.name);
                }
            };
            console.log(Object.getOwnPropertyNames(obj)); // => ["name", "age", "sayHello"] :返回对象的实例成员
    
    
    • Object.getPrototypeOf(object) :返回对象的上一级原型
    • 参数:
      • object {object} :对象
    • 返回值:
      • {object} 返回原型对象
    // 1.对象直接量
            var obj = {
                name: 'tom',
                age: 22,
                sayHello: function () {
                    alert('Hello' + this.name);
                }
            };
            console.log(Object.getPrototypeOf(obj)); // => Object 对象:对象直接量的原型为Object
             
    // 2.自定义对象
            var People = function (name) {
                this.name = name;
            };
             
            var p = new People('tom');
            var people = Object.getPrototypeOf(p);
            console.log(people); // => People 对象:new 创建的对象使用构造函数的prototype属性作为他们的原型
            console.log(Object.getPrototypeOf(people)); // => Object 对象:原型People的原型为Object
    
    • Object.isExtensible(object) :判断是否可向对象添加新的属性
    • Object.isFrozen(object) :判断对象是否冻结;true:不能修改对象的现有属性特性和值并且不能添加新的属性
    • Object.isSealed(object) :判断对象是否封闭;true:不能修改对象的现有属性特性并且不能添加新的属性
    • Object.keys(object) :返回一个数组,包含对象的可枚举的实例属性名称
    • 参数:
      • object {object} :对象
    • 返回值:
      • {Array} 返回一个数组,包含对象可枚举的实例属性名称
      • 此方法与getOwnPropertyNames()类似,但getOwnPropertyNames()包含了可枚举和不可枚举的成员
    //示例 :
            var obj = {
                name: 'tom',
                age: 22,
                sayHello: function () {
                    alert('Hello' + this.name);
                }
            };
             
            //getOwnPropertyNames与keys方法返回的内容都相同
            console.log(Object.getOwnPropertyNames(obj)); // => ["name", "age", "sayHello"] :返回对象的所有实例成员
            console.log(Object.keys(obj)); // => ["name", "age", "sayHello"] :返回对象的所有可枚举成员
             
    // 设置对象的name属性不可枚举
            Object.defineProperty(obj, 'name', {
                    enumerable: false
                }
            );
             
            //keys方法,只包含可枚举成员
            console.log(Object.getOwnPropertyNames(obj)); // => ["name", "age", "sayHello"] :返回对象的所有实例成员
            console.log(Object.keys(obj)); // => ["age", "sayHello"] :返回对象的所有可枚举成员
    
    • Object.preventExtensions(object) :设置对象不能添加新的属性
    • 参数:
      • object {object} :对象
    • 返回值:
      • {object} 返回此对象
    //示例 :  
            var obj = {
                name: 'tom',
                age: 22
            };
            Object.preventExtensions(obj); // 设置对象不能添加新的属性
            obj.email = '123@qq.com';
            console.log(obj.email); // => undefined :无法向对象添加新的属性
    
    • Object.seal(object) :密封对象,使其无法修改现有属性的特性以及不能添加新的属性
    • 参数:
      • object {object} :对象
    • 返回值:
      • {object} 返回此对象
    //示例 :
            var obj = {
                name: 'tom',
                age: 22
            };
            Object.seal(obj); // 密封对象
            obj.email = '123@qq.com';
            console.log(obj.email); // => undefined :无法向对象添加新的属性
     
            // 报异常:无法修改对象属性的特性
            Object.defineProperty(obj, 'name', {
                    enumerable: false
                }
            );
    
  17. 属性描述符

    • 属性描述符分为 "数据属性" 和 "访问器属性" ;
    • 两者可相互转换,若转换后未设置enumerable和configurable特性(两类属性描述符都包含这2个特性),
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352

推荐阅读更多精彩内容