JS对象进阶:构造函数创造对象 原型继承 原型链 原型对象扩展方法 constructor指回 create继承 keys defineProperty详细用法

JS对象进阶

本章会给大家介绍构造函数创造对象,原型继承,原型链,原型对象怎么扩展方法,还有constructor,create,keys,difinePropertyu方法

1.构造函数创造对象

function Example(name,age){
            this.name=name;
            this.age=age;
            this.methods=function(){
                console.log('this is methods');
            }
        };
        var tx=new Example('tx',20);
        console.log(tx);
        console.log(tx.age);
        console.log(tx.name);
        tx.methods();

在这里插入图片描述

先创造一个构造函数,然后创造实例化对象。这里可以看到输出结果。

  • 在这个构造函数中,实例成员就是构造函数内部通过this添加的成员 name age methods就是实例成员。
  • 在构造函数本身上添加的成员就为静态成员 例如Example.sex='男'
  • 实例成员只能通过实例化对象访问
  • 静态成员只能通过构造函数访问
    例如:
        Example.sex='男'//这是静态成员
        console.log(tx.sex);//undefined /实例对象访问静态成员
        console.log(Example.sex);//男 /构造函数访问静态成员
        console.log(Example.age);//undefined /构造函数范文实例成员
        Example.methods();//报错 /构造函数范文实例成员

2.prototype和__proto__的详细介绍

  • 首先需要知道JS是面向对象的语言,拥有继承和原型。
  • 简单得来说:对象除了可以保持自有的属性,还可以从一个称为原型的对象继承属性。
  • 大家可以观察下面的图片,清晰认识什么是原型

在这里插入图片描述

        console.log(Example.prototype);
        //这是构造函数原型
        console.log(tx.__proto__);
        //这是实例化对象原型
        console.log(Example.prototype.__proto__);
        //这是构造函数原型的原型(以及到达顶层原型)
        console.log(Object.prototype);
        //这是对象的原型(这是顶层原型)
        console.log(Example.prototype.__proto__.__proto__);
        //这是构造函数原型的原型的原型为null  超过了顶层原型
        console.log(Object.prototype.__proto__);
        //超过了顶层原型

在这里插入图片描述
相信大家对原型有了一点认识 关于prototype和__proto__的不同在于:
prototype是用在构造函数或者Object后面,__proto__是用在实例对象后面。 他们的意思都一样,返回原型对象!

对象可以利用原型的属性和方法:

        tx.__proto__.sex='男';
        Example.prototype.birthday='2000-02-18';
        console.log(tx.sex);//男
        console.log(tx.birthday);//2000-02-18

如果实例对象里存在的属性名和他的原型里的属性名相同时,调用属性名会遵从就近原则,简单说就是:

  • 首先查看对象本身有无这个属性
  • 再找它的构造函数的原型 若没构造函数就找Object原型
  • 最后找Object原型
    就是这样寻找!

3.constructor指回
constructor 记录该对象引用于那个构造函数,很多情况下,我们需要手动利用constructor这个属性指回原来的构造函数。

首先要知道,我们刚才给构造函数的原型加了2个属性,输出一下构造函数的原型大家可以看看:

console.log(tx.__proto__);
console.log(Example.prototype);

在这里插入图片描述

console.log(tx.__proto__.constructor);
console.log(Example.prototype.constructor);

在这里插入图片描述
这就是 constructor的一个用法!

constructor还有一个用法就是:如果我们修改了原来的原型对象,给原型赋值是一个对象,必须手动利用constructor这个属性指回原来的构造函数

4.create()继承
create()继承可以直接继承顶部原型,也可以继承原型,还可以继承对象
例如:

 var obj1=Object.create({x:1,y:2}); 
 //继承一个原型 再继承顶部原型 间接继承Object.prototype
 console.log(obj1);
console.log(obj1.__proto__);
console.log(obj1.__proto__.__proto__);

在这里插入图片描述

会得到一个空对象,但是这个obj1.__proto__为刚才的{x:1,y:2}对象,然后再往上面继承就是Object.prototype,顶层原型了。

同样也可以继承空对象和直接继承顶层原型

let obj2=Object.create(null); //obj2不继承任何属性和方法
let obj3=Object.create(Object.prototype);//直接继承顶部原型

5.Object.keys() 获取对象本事所有的属性 返回一个数组。

var obj={
            id:1,
            pname:'iphone',
            price:5000,
            num:1
        };
        var arr =Object.keys(obj);
        //获取对象本事所有的属性
        console.log(arr);
        arr.forEach(function(value){
            console.log(value);
        })

在这里插入图片描述
6.defineProperty详细用法介绍 :

语法:Object.defineProperty(obj.prop,descriptor)
用法: 定义新属性或者修改原有的属性
obj 必须存在,表示目标对象
prop 必须存在,表示需定义或修改的属性的名字
descriptor 必须存在,表示目标属性所拥有的特性
前面2个参数都很好理解,就是要修改的目标对象和属性名

descriptor以对象{}书写,里面4个用法如下:

  • value:设置属性的值 默认为undefined
  • writable:值是否可以重写 ture||false 默认false
  • enumerable:目标属性是否可以被枚举 ture||false 默认false
  • configurable:目标属性是否可以被删除或是否可以再次修改特性 ture||false 默认false

我给大家演示各个属性的用法:

  1. value,设置值
var obj={
            id:1,
            pname:'iphone',
            price:4999
        };
        Object.defineProperty(obj,'num',{
            value:1000
        });//增加一个属性
        Object.defineProperty(obj,'price',{
            value:'100'
        });//修改一个属性
        console.log(obj);

在这里插入图片描述
2. writable,值是否可以重写

Object.defineProperty(obj,'id',{
            writable:false, //不允许修改id这个属性值
        });
        
        obj.id=2;//尝试修改id值
        console.log(obj);//id不能被修改 依旧为1

在这里插入图片描述

  1. enumerable:目标属性是否可以被枚举
    这个方法用在 比如:目标的属性比较有隐私特征的时候(地址,身份证),
    可以用enumerable让这个属性不能被枚举出来。
    给一个address保存地址,让地址不被枚举出来
Object.defineProperty(obj,'address',{
            value:'中国四川省',//隐私 不能枚举出来
            enumerable:false, //不会遍历出来
        });
        console.log(Object.keys(obj));

在这里插入图片描述
并没有吧address这个属性枚举出来!

4.configurable:目标属性是否可以被删除或是否可以再次修改特性
一般来说,有的商品的标价不能被删除,商品的编号不能被再次修改它的特性(让编号不能修改等特性)
首先请看如何让标价不能被删除:

Object.defineProperty(obj,'price',{
            configurable:false,//不能删除或修改特性
        });
        delete obj.price
        console.log(obj);

在这里插入图片描述

价格依旧存在并未删除

请看不能修改特性:

 Object.defineProperty(obj,'address',{
            value:'中国四川',//隐私 不能枚举出来
            enumerable:false, //不会遍历出来
            configurable:false,
        });

        Object.defineProperty(obj,'address',{
            enumerable:true,
            configurable:true
        });

在这里插入图片描述
我们在上面已经设置了address这个属性不能修改并且不能修改这个属性的特征,我们下面又来设置它的特征,会直接报错,不能修改它的特征!

要介绍的内容就到这里了,希望大家能指出我的不足和错误,希望可以多私聊我和我沟通交流,希望大家多点赞支持,谢谢大家!!!

  • 23
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值