【对象——对象及原型链上的属性——对象的操作方法 ——原型与in操作符】

发布于:2023-01-24 ⋅ 阅读:(14) ⋅ 点赞:(0) ⋅ 评论:(0)

什么是对象,其实就是一种类型,即引用类型。而对象的值就是引用类型的实例。
在ECMAScript中引用类型是一种数据结构。用于将数据和功能组织在一起,它也常被称做为类,但ECMAScript中却没有这种东西。虽然ECMAScript是一门面向对象的语言。却不具备传统面向对象语言所拥有的类和接口等基本结构。

万物皆对象,除了数字,字符,布尔这种绝对值以外的所有部分都是对象,对象是类的实例化体现,类是对象的抽象体现。

新建对象

1var obj=new Object();
2var obj={}3var obj=Object.create();

new Object()

var obj=new Object();
obj.属性=属性值
obj.方法=方法函数
obj[属性]=属性值
obj[方法]=方法函数

中括号中的属性和方法必须是字符串,如果是变量,该内容必须是字符型变量。

var arr=new Object([])

创建数组,在javascript中数组不是单独的类型,它是由对象扩展出来的,因此,可以使用这种形式来建立数组。

var obj={}

var obj={
	属性:属性值,
	方法:方法函数
}

花括号在语言中是指代码块的意思,在obj也相当于一个代码块。obj自身在使用中可以完成和丰富各种代码块。

function abc(){
	return {
	       属性:属性值,
	      方法:方法函数
	}
}

在函数中,有时候需要返回一个对象,这时候,我们通常使用花括号的形式来返回对象

Object.create()

以某个对象作为原型创建一个新对象

Object.create(proto, [ propertiesObject ])
var obj = {
    a: 1,
    b: 2
}
var o1 = Object.create(obj);
__proto__ 对象的原型链
console.log(o1.__proto__);{a: 1, b: 2}

对象获取属性时,首先查看自身有没有该对象属性,如果没有则向下查找其原型链中有没有该原型属性
对象属性 该对象自身的属性
原型属性 该对象原型链中的属性
如果在原型链属性中有多个相同的属性,那么查找离自己最近的原型链属性
对象设置属性时,一定设置的是该对象的属性而不是原型链上的对象属性

var obj = {
    a: 1,
    b: 2
}
var o1 = Object.create(obj);
o1.c=3;
for(var key in o1){
    console.log(o1[key]);
}

3
1
2

工厂模式
构造函数模式
原型模式

  • proto对象原型
  • propertiesObject 一组属性和值,该参数对象不能是 undefined,
    另外只有该对象中自身拥有的可枚举的属性才有效,也就是说该对象的原型链上属性是无效的。该方法可以针对已知对象创建新对象也可以创建一个空对象。

对象的操作方法

对象.hasOwnProperty(属性名) 判断该属性是否是对象的对象属性

var obj = {
    a: 1,
    b: 2
}
var o1 = Object.create(obj);
o1.c=3;
for(var key in o1){
    console.log(o1.hasOwnProperty(key),key,o1[key]);
}


true 'c' 3
false 'a' 1
false 'b' 2

Object.keys(对象) 获取该对象的可枚举对象属性名组成数组
Object.values(对象) 获取该对象的可枚举对象属性值组成数组
对象1.isPrototypeOf(对象2) 判断对象1是不是对象2的原型链其中一个原型

delete

delete
删除对象的属性
var obj={a:3,b:4}
delete obj.a;
可以根据键值删除对象下的属性。

assign()
assign 复制对象,浅复制,只能复制第一层
可将o对象的所有可枚举对象属性复制到o1上,不能将原型链属性复制
可将o的对象属性复制到空对象中并且返回赋值给o3
assign 将多个对象复制到一个对象上,如果出现重复属性,就会把后面的覆盖前面的

Object.assign(target, ...sources)
Object.assign(o1,o);
var o2 = Object.assign({},o1);
var o3=Object.assign({},o1,o2,o);

Object.assign() 方法用于将所有可枚举的属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
如果目标对象中的属性具有相同的键,则属性将被源中的属性覆盖。后来的源的属性将类似地覆盖早先的属性。

  • 1、复制一个对象,注意如果我们用var obj=obj1这是引用,两者间会产生联系
  • 2、合并拷贝因此,我们使用复制这种方法
  • 3、继承属性和不可枚举的属性是不能被拷贝的

defineProperties
给对象定义属性值

Object.defineProperties(obj, props)

Object.defineProperties(对象,{
	“属性名”:{
	     value:属性值,
	    writable:布尔值
	}
}

属性名必须是字符串,value后面的内容是属性的值,writable是该属性是否可写。

defineProperty()
详细定义对象的属性
Object.defineProperty(对象,属性名,该属性值的描述对象)

Object.defineProperty(obj, prop, descriptor)
var obj={};
Object.defineProperty(obj,“属性名”,{
	enumerable: false,
  	configurable: false,
  	writable: false,
  	value: 属性值
})

configurable   是否可写可删除。默认为 true。
当没有设置这个描述对象的对应属性时,则默认为false

enumerable    是否可被枚举。默认为 true。
value     该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。
writable   是否可写。默认为 true

writable,value和set,get冲突,不能同时使用

Object.defineProperty(obj,"a",{
    configurable:true,//是否可以删除该属性或者是否可以修改当前对象值的描述对象
    enumerable:true,//是否可以枚举该属性值
    writable:true,//是否可以修改该属性值
    value:1//对象当前属性的值
})


get: function reactiveGetter() {
	console.log('get value')
	return val
},
set: function reactiveSetter(newVal) {
	console.log('change value')
	val = newVal
}

Object.defineProperties给对象定义多个属性和方法,设置他们的描述对象

Object.defineProperties(obj,{
    a:{
        value:3
    },
    b:{
        enumerable:true,
        value:4
    },
    c:{
        configurable:true,
        writable:true,
        value:10
    },
    d:{
        value:function(){
            console.log("play")
        }
    }
})

getOwnPropertyNames
获取对象对象属性名是字符类型的属性名,组成的新数组
getOwnPropertySymbols
专门获取对象的Symbol属性的数组
Reflect 对象的映射对象类型
获取对象的全部属性值

var obj={a:1,b:2,c:3}
var arr=Object.getOwnPropertyNames(obj);
打印显示的是[a,b,c]
var obj = {
     a: 1,
     b: 2,
     Symbol:3
 }
obj[Symbol()] =4
var arr=Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj));
var arr=[...Object.getOwnPropertyNames(obj),...Object.getOwnPropertySymbols(obj)];
console.log(arr)

Reflect 对象的映射对象类型

var arr=Reflect.ownKeys(obj);
console.log(arr)
//['a', 'b', 'Symbol', Symbol()]

Object.getOwnPropertyDescriptor(对象,属性) 获取对象的某个属性的描述对象
Object.getOwnPropertyDescriptors(obj)获取对象的所有属性的描述对象获取一个对象

console.log(Object.getOwnPropertyDescriptor(obj,"a"));
console.log(Object.getOwnPropertyDescriptors(obj));

将对象转换为迭代器

var o = Object.entries({
    a: 1,
    b: 2
});
console.log(o)
var o={a:1,b:2}
var m=new Map(Object.entries(o));
console.log(m)

在这里插入图片描述

将迭代器转换为对象,可以将map类型转换为对象类型

var o=Object.fromEntries([["a",1],["b",2]]);
console.log(o)//{a: 1, b: 2}
var m=new Map();
m.set("a",1);
m.set("b",2);
console.log(m);//{'a' => 1, 'b' => 2}
var o=Object.fromEntries(m);
console.log(o)//{a: 1, b: 2}

freeze()

冻结对象,使用该方法以后,不能修改该对象的所有属性,不能删除所有属性。
Object.freeze(o); 冻结对象,不可添加,不可删除,不可修改

Object.freeze(obj)
const COLOR={YELLOW:"yellow",RED:"red",BLUE:"blue",GREEN:"green"};
Object.freeze(COLOR);

判断对象是否被冻结

Object.isFrozen(COLOR)

Object.seal(o);密封
将对象密封 对象属性不可删除,不可扩展,但是可以修改对象的属性值

var o={a:1,b:2,c:3,d:4};
Object.seal(o);//密封
o.a=10;
o.e=20;
delete obj.a;
console.log(o)
判断对象是否被密封
console.log(Object.isSealed(o));
``
**不可扩展**
可以修改对象属性,可以删除对象属性,但是不能给对象添加新属性

```javascript
var o={a:1,b:2,c:3,d:4};
Object.preventExtensions(o);//不可扩展
delete o.a;
o.b=10;
o.e=20;
console.log(o)//{b: 10, c: 3, d: 4}

判断对象是否可扩展
console.log(Object.isExtensible(o));

Object.getPrototypeOf(o1)获取对象的原型链 等同于 o1.__proto__
获取对象原型链

Object.setPrototypeOf(对象,原型对象)
给已有的对象设置一个原型链

var o={a:1,b:2};
var o1={c:10};
Object.setPrototypeOf(o,o1);
console.log(o);


等价于
o.__proto__=o1;
console.log(o)

判断对象的,某个属性是不是他的对象属性,而不是原型属性

var o={a:1,b:2};
var o1=Object.create(o);
o1.c=3;
console.log(Object.hasOwn(o1,"c"));
console.log(Object.hasOwn(o1,"a"));
console.log(o1.hasOwnProperty("a"))//等同于

判断两个值是否绝对相等,与===相似
Object.is(值1,值2)

console.log(Object.is(1,"1"))
可以判断是否等于NaN
console.log(Object.is(Number("a"),NaN));
var o={a:1};
Object.defineProperty(o,"b",{
	value:2
})
// 判断属性是否是对象的可枚举属性
console.log(o.propertyIsEnumerable("a"))//true
console.log(o.propertyIsEnumerable("b"))//false

常用判断方法集合

  • Object.is(value1, value2);判断两个对象或者两个内容是否相等, 这种相等性判断逻辑和传统的 == 运算符所用的不同,== 运算符会对它两边的操作数做隐式的类型转换(如果它们是不同类型的值的话),然后才进行相等性比较,(所以才会有类似 “” == false 为 true 的现象),但 Object.is 不会做这种类型转换。
  • Object.isExtensible(obj) 判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)。
  • Object.isFrozen(obj)判断一个对象是否被冻结 frozen。

原型与in操作符

有了两种方式使用in单独使用和在for-in循环中使用,在单独使用时,in操作符会在通过对象能够访问给定属性时返回true。无论该属性存在于实例对象,还是原型中。for-in只会遍历实例对象中可枚举属性。
那么如何确定这个属性时对象还是原型中的属性呢?
Object.hasPrototypeProperty(属性)只能返回当前实例对象身上的属性,如果in返回的是true,而hasPrototypeProperty返回false就可以确定是原型的属性。