您的位置:首页 > 移动开发 > Objective-C

带你认识不一样的对象,Object中追加属性以及assign、isPrototypeOf等大多对象方法以及深复制的使用

2020-08-16 16:21 1501 查看

对象

原型链 obj是最底层的

var obj = {a:1};
console.log(obj)//在打印obj时obj下面会有一个proto属性,这个东西成为原型链。
console.log(obj.__proto__)//也可以使用obj.__proto__来直接打印
class Box{
constructor(){

}
aaa(){

}
bbb(){

}
}//创建一个类
var b = new Box();//创建一个实例化对象
b.ccc=function(){//给实例化对象添加一个方法ccc

}
console.log(b)
//此时b中的只有ccc一个方法而aaa和bbb都在实例化对象原行b的原型链上 可以使用b.aaa来直接调用原型链上的方法
class Ball extends Box{
constructor(){
super()
}
ccc(){

}
}//创建一个Ball类继承Box的方法
var b = new  Ball();
console.log(b)//此时b对象上的原型中就多了一个Box类 当继承的类型越来越多就会形成一条原型链  继承的类或方法存在于原型链中

所以万物皆对象,任何东西最底层的都是对象。

在对象中有三种创建方法。

var obj = {a:1}//字面量创建
var obj = new Object()//构造函数创建
var obj = Object.create()//以原型创建
//对象中的key必须是String或者Symbol类型,如果不是就会隐式转换为String类型
var o={a:1};
obj[o]=10;
console.log(obj[{b:3}]);//结果为10 对象会自动转化为字符串object
var arr=[0];
bj[arr]=100;
console.log(obj[0])//结果为100 数组转化为字符串会用逗号分开每一个值

重点说明一下第三种创建,前面两种没啥说的

var o = {a:1};
var o1 = Object.create(o)//以o为原型创建o1,此时在o1中就会有o对象这个原型
console.log(o1.__proto__===o)//true他们就是一样的 引用地址是相同的
//所以不能直接改变原型o中的数据这样会导致所有以o为原型的对象中的数据都发生改变
console.log(o1.a)//此时o1中没有a属性 所以在他的原型上查找 所以返回为1
o1.a=10;
consloe.log(o1.a)//当o1中具有a属性时 先返回o1上的属性值
var obj={
a:1,
b:100,
c:this.b,
// 在对象的属性下使用this,this将指向对象外的this指向
}//因为在你调用this时你这个obj还没有创建完成,所以他就会指向外部的this。
console.log(obj.c)为undefined

当设置对象属性时,直接设置的时对象的自身属性

如果获取时,首先查看对象有没有这个名称的对象属性,如果有则直接返回,如果没有向下查找紧邻的原型链中的属性是否具有该属性名,查找到距离该对象最近的原型链中的属性名后返回其值。

对象的assign方法

var o = {a:1,b:2};
var o1 = Object.assign({},o)

原理就是创建一个新对象,并且将o上的属性复制到这个新对象上,然后返回这个对象。

不过这种方法复制对象时是浅复制,仅把第一层的属性复制到新对象上,如果第一层的属性值是引用类型,则会把引用地址赋值给新对象上。

Object.assign()将一个或者多个对象种可枚举属性赋值到第一个参数对象种,如果后面的对象属性与前面的对象属性相同时,则会覆盖前面的对象属性。

var o1={a:1,b:2,c:3};
var o2={d:4,e:5,f:6};
var o3={a:7,e:8,c:9};
Object.assign(o,o1,o2,o3);

原对象种增加复制的属性,引用地址不变;

var o1={a:1,b:2,c:3};
var o2={d:4,e:5,f:6};
var o3={a:7,e:8,c:9};
var o4={...o1,...o2,...o3}//相当于将o1,o2,o3所有属性解构产生新对象赋值给了o4;

对象的属性创建

使用Object.defineProperty()

参数类型为:对象,属性名,该属性的描述对象

var obj = {};
Object.defineProperty(obj,'a',{
configurable:true,//该属性是否可以删除
enumerable:true,//该属性是否可以枚枚举
writable:true,//该属性是否可写(不是只读)
value:10//该属性的值
})
var obj = {};
Object.defineProperty(obj,'a',{
configurable:false,
value:10//该属性的值
})
delete obj.a//此时无法删除该属性
var obj = {};
Object.defineProperty(obj,'a',{
configurable:true,
enumerable:false,//不可枚举
writable:true,
value:10
})
console.log(obj)//此时发现a时一个不可枚举的属性

不可枚举属性简单来说就是你无法用for in来获取遍历,他是不想暴露的属性。

var obj = {};
Object.defineProperty(obj,"a",{
configurable:true,
enumerable:true,
writable:false,//不可写
value:10
})
obj.a=100;//修改无效,他是一个只读属性

当你啥都没写时,他们的默认值都为false

Object.defineProperty(obj,"a",{
// 描述属性省略时默认值是false
//意思为他无法被删除,修改同时也是不可枚举属性
value:function(){
console.log("aaa");
}
})
Object.defineProperties()

当需要追加多个属性和属性值时,可以使用这个方法

var obj= {};
Object.defineProperties(obj,{
a:{
enumerable:false,
writable:true,
configurable:true,
value:10
},
b:{
writable:true,
configurable:true,
value:function(){

}
},
c:{
configurable:true,
value:100
}
})
Object.freeze()

ES6中没有常量,不过你可以使用objec.freeze()这个方法来冻结对象,他的参数为一个对象

var obj = {a:1};
Object.freeze(obj)//冻结对象,此时他无法增加追加删除
delete.obj.a//无法删除
obj.b=100;//无法增加
obj.a=100//无法修改
Object.getOwnPropertyNames()

获取对象的所有属性名,同时包括不可枚举属性,参数为需要获取的对象

Object.getOwnPropertyDescriptor()

获取对象属性的描述对象,参数为需要获取的对象和属性名称。

以为我们有时候需要遍历到对象中所有属性和属性值,使用for in时无法遍历到不可枚举对象,此时利用上述两种方法就可以完成对象的遍历。

Object.defineProperties(obj,{
a:{
value:1
},
b:{
enumerable:true,
value:2
},
c:{
writable:true,
value:3
}
});
obj.d=10;
obj.e=100;
var arr=Object.getOwnPropertyNames(obj);
for(var i=0;i<arr.length;i++){
console.log(arr[i],obj[arr[i]]);
var disc=Object.getOwnPropertyDescriptor(obj,arr[i]);
console.log(disc);
}
Object.is()

用来判断两个参数是否相等,类似于全等(===),返回一个Boolean值

但是和全等不同的时使用object.is判断NaN时是相等的

console.log(object.is(NaN,NaN))

另外还有一些方法返回的都是Boolean值

console.log( Object.isExtensible(obj));//判断对象是可以增加属性
console.log(Object.isFrozen(obj))//判断对象是否冻结
obj.hasOwnProperty()

用来判断对象中是否存在这个属性,类似于in,不过和in不同的是,它所判断的是当前对象的对象属性,原型链不属于当前范围,而用in判断是否存在时,它所判断的时当前对象和对象原型链中所有属性都可以判断

var o={a:1,b:2};
var o1=Object.create(o);
console.log(o1.hasOwnProperty("a"));//false,当前对象的对象属性,原型链属性不属于范围
console.log("a" in o1);//true
isPrototypeOf()

用来判断一个类的父类是否用于这个类

class Box{
constructor(){

}
play(){

}
}
class Ball extends Box{
constructor(){
super();
}
run(){

}
}
console.log(Box.isPrototypeOf(Ball));//Ball的父类是否有Box类
var a=new Ball();
console.log(Box.isPrototypeOf(a.constructor));//b对象的父类中有没有Box类
propertyIsEnumerable()

用来查询属性是不是可枚举属性

var obj = {a:1,b:2}
console.log(obj.propertyIsEnumerable("b"))
instanceof

用来判断实例化对象中的原型上有没有这个类

class Box{
constructor(){

}
play(){

}
}
class Ball extends Box{
constructor(){
super();
}
run(){

}
}
var b=new Box();
console.log(b instanceof Box);
console.log(b instanceof Ball);

对象深复制的封装

function cloneobj(source,target){
if(target===undefined) target = {};
var names = Object.getOwnPropertyNames(source);
for(var i = 0; i < names.length;i++){
var desc = Object.getOwnPropertyDescriptor(source,names[i]);
if(typeof desc.value==='object' && desc.value !== null){
var obj;
switch(true){
case desc.value.constructor === Date:
obj = new Date(desc.value.toString());
break;
case desc.value.constructor === RegExp:
obj = new RegExp(desc.value.source,desc.value.flags);
break;
case HTMLElement.isPrototypeOf(desc.value.constructor):
obj = document.createElement(desc.value.nodeName);
break;
default:
obj = new desc.value.constructor()
}
Object.defineProperty(target,names[i],{
enumerable : desc.enumerable,
writable : desc.writable,
configurable : desc.configurable,
value : obj
})
cloneobj(desc.value,obj)
}else{
Object.defineProperty(target,names[i],desc)
}
}
return target
}

使用时直接调用:

var obj = {
a: 1,
b: 2,
c: [1, 2, 3],
z: document.createElement("div"),
d: {
e: new Date(),
f: /a/g,
g: function (s) {
console.log(s);
},
h: {

}
}
}
Object.defineProperties(obj.d.h, {
i: {
value: 10
},
j: {
configurable: true,
value: [1, 2, 3, 4]
},
k: {
writable: true,
value: {
l: {},
m: "abcde",
n: true,
o: [1, 2, 3]
}
}
})
Object.defineProperties(obj.d.h.k.l, {
p: {
value: function () {
console.log("p")
}
},
q: {
value: {
r: { a: 1 },
j: { b: 2 }
}
}
});
var o ={a:1};
o = cloneobj(obj);
console.log(o)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐