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
我给大家演示各个属性的用法:
- 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
- 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这个属性不能修改并且不能修改这个属性的特征,我们下面又来设置它的特征,会直接报错,不能修改它的特征!
要介绍的内容就到这里了,希望大家能指出我的不足和错误,希望可以多私聊我和我沟通交流,希望大家多点赞支持,谢谢大家!!!
转载:https://blog.csdn.net/qq_52168812/article/details/115599437