/**
* Object相关方法的学习
*/
const obj = {
name: "foo",
age: "23",
sax: true,
};
// 常规修改 添加对象的方法
obj.name = "foo1";
obj.xx = 1234;
/**
* es5 新增的修改和添加对象的方法 object.defneProperty(obj,props,description)
* obj: 要修改的对象名称
* props:要修改或添加对象里面的属性的名称
* description: 针对属性名称的说明 他也是一个对象
*
* description:{
* value:设置属性的值
* writable:是否可以重写 true | fasle 默认为fasle
* enumerate:是否可以背枚举 true | false 默认为false 是否可以被便利Object.keys
* configurable:目标属性是否可以被删除或是否可以被再次修改 true | false 默认false
* }
*/
Object.defineProperty(obj, "yy", {
value: 1000,
writable: false,
enumerable: false,
configurable: false,
});
console.log(obj);
obj.yy = 999; // 修改无效
console.log(obj);
delete obj.yy; // 删除无效
console.log(obj);
console.log(Object.keys(obj)); // yy不会被便利出来 [ 'name', 'age', 'sax', 'xx' ]
/**
* object.is
* es5 中比较两个值是否相等,一般会用 == ===
* 他们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0 等 -0
* ES6提出了同值相等的算法来解决这个问题,object.is就是部署了这个算法的新方法,他用来比较两个值是否严格相等,与 === 算法基本一致
*/
console.log(Object.is(-0, +0)); // false
console.log(-0 === +0); // true
console.log(Object.is(NaN, NaN)); // true
console.log(NaN === NaN); // false
console.log(Object.is("1", 1)); // false
const objj = {};
console.log(Object.is(objj, {})); // false
Object.is(null, null); // true
Object.is(undefined, undefined); // true
Object.is(window, window); // true
Object.is([], []); // false
const fooo = { a: 1 };
const bar = { a: 1 };
const sameFoo = fooo;
Object.is(fooo, fooo); // true
Object.is(fooo, bar); // false
Object.is(fooo, sameFoo); // true
Object.is(NaN, 0 / 0); // true
Object.is(NaN, Number.NaN); // true
/**
* Object.assign(target,sources1,source2)
* 用于将源对象所有可枚举的属性赋值到目标对象,如果对象相同,前者会覆盖后者
* 如果有多个值,可以用ES6的新语法对象解构{...a}
*/
const obj1 = { a: 1, b: 2, c: 3, d: 4 };
const obj2 = { c: 5, d: 6, e: 7 };
Object.assign(obj1, obj2);
console.log(obj1);
const obj3 = { ...obj1, ...obj2 };
console.log(obj3);
/**
* Object.getPrototypeOf()
* 接收一个对象 返回该参数对象的原型
*/
console.log(Object.getPrototypeOf({}) === Object.prototype); // true
console.log(Object.getPrototypeOf(Object.prototype) === null); // true
console.log(Object.is(Object.getPrototypeOf({}), Object.prototype)); // true
/**
* Object.getPrototypeOf 和 Object.setPrototypeOf
* get是获取该对象上的原型属性,并返回该对象
* set是设置该对象上的原型属性,并返回该对象
*/
const obj4 = { a: 1, b: 2 };
const obj5 = { x: 1 };
// 设置obj4上的原型上的属性
Object.setPrototypeOf(obj4, obj5); // 返回对象本身
// 这里实际访问的是obj4.prototype.x的方法
console.log(obj4.x);
console.log(Object.getPrototypeOf(obj4, obj5.x)); // 返回指定对象的原型 =》{x:1}
/**
* Object.create
* 创建一个对象
*
*/
const person = {
ishuman: false,
printIntro: function () {
console.log("i am human");
},
};
// 在person1的原型上添加了person对象,person1本身没有ishuman printIntro这些属性
const person1 = Object.create(person);
// person1.ishuman = true;
// person1.name = "John";
console.log(person);
console.log(person1);
// Shape——父类
function Shape() {
this.x = 0;
this.y = 0;
}
/**
* 用Object.create 实现继承
* 需要注意的是,使用 create() 也有一些要注意的地方,比如重新添加 constructor 属性以确保正确的语义。
* 虽然 Object.create() 被认为比使用 Object.setPrototypeOf() 修改原型更具有性能优势,
* 但如果没有创建实例并且属性访问还没有被优化,它们之间的差异实际上是可以忽略不计的。
* 在现代代码中,无论如何都应该优先使用类语法。
* @param {*} x
* @param {*} y
*/
// 父类方法
Shape.prototype.move = function (x, y) {
this.x += x;
this.y += y;
console.info("Shape moved.");
};
// Rectangle——子类
function Rectangle() {
Shape.call(this); // 调用父类构造函数。
}
// 子类继承父类
Rectangle.prototype = Object.create(Shape.prototype, {
// 如果不将 Rectangle.prototype.constructor 设置为 Rectangle,
// 它将采用 Shape(父类)的 prototype.constructor。
// 为避免这种情况,我们将 prototype.constructor 设置为 Rectangle(子类)。
constructor: {
value: Rectangle,
enumerable: false,
writable: true,
configurable: true,
},
});
const rect = new Rectangle();
console.log("rect 是 Rectangle 类的实例吗?", rect instanceof Rectangle); // true
console.log("rect 是 Shape 类的实例吗?", rect instanceof Shape); // true
rect.move(1, 1); // 打印 'Shape moved.'
/**
* Object.entries 返回一个数组,包含给定对象的可枚举的字符串健直对属性
* Object.formEntries 将健直对的数组转换成一个对象
*/
const object = { a: 1, b: 2 };
// 使用 for of循环
for (const [key, value] of Object.entries(object)) {
console.log(key, value); // "object a,1 b,2
}
//使用forEach循环
Object.entries(object).map(([key, value]) => {
console.log(key, value); // a,1 b,2
});
// 字符串具有索引作为可枚举的自有属性
const foo = "bar";
Object.entries(foo); // [ [0,b],[1,a],[2,r] ]
//其他基本类型(除了 undefined 和 null)没有自有属性
console.log(Object.entries(100)); // []
// 将object转换成Map
const m = { foo: "bar", baz: 22 };
const map = new Map(Object.entries(m));
console.log(map); // Map(2) {"foo" => "bar", "baz" => 42}
const entries = new Map([
["foo", "bar"],
["baz", "12"],
]);
const newen = Object.fromEntries(entries);
console.log(newen); // {foo: "bar", baz:'12'}
/**
* Object.freeze()
* 对象冻结,等于是不允许对其进行任何操作,他也是将现有的属性的描述属性
* configurable = false writable = false 所以无法向冻结的对象中增删改任何属性
* 通常如果设置之后进行操作,会是静默失败不会任何反应,但是use strict模式下 会抛出错误
*/
const freezeObj = { prop() {}, foo: "bar" };
// 冻结前
freezeObj.foo = "baz";
freezeObj.fee = "babiq";
delete freezeObj.prop;
// 冻结
const newFreezeObj = Object.freeze(freezeObj);
newFreezeObj === freezeObj; // true
freezeObj.foo = "baq"; // 没有任何反应 他还是等与 baz,严格模式下会报错
// 判断对象是否冻结
Object.isFrozen(freezeObj); // 返回true
/**
* Object.getOwnPropertyDescriptor(obj,prop)
* 返回一个描述属性的对象,并可以对相关属性进行设置
* Object.getOwnPropertyDescriptors(obj)
* 返回这个对象里面的所有的属性的描述属性的说明的一个对象,并可以对相关属性进行设置,同上面方法一样
*/
const ownObj = { pro: 42 };
const descript = Object.getOwnPropertyDescriptor(ownObj, "pro");
console.log(descript); // {configurable : true, enumerable : true, value : 42,writable: true}
descript.configurable = false;
console.log(descript); // {configurable : false, enumerable : true, value : 42,writable: true}
// 如果对象不存在 返回undefiend
const descript = Object.getOwnPropertyDescriptor(ownObj, "xx");
/**
* Object.getOwnPropertyNames(obj)
* 返回一个数组,该对象上直接关联的所有属性包括不可枚举的属性,通过对应的属性形成的下标组成一个数组
*/
const arr = ["a", "b", "c"];
// 这里的length属性是应为数组本身有一个length属性,
//当使用Object.getOwnPropertyNames获取数组的所有属性时,length也会被包含进去
console.log(Object.getOwnPropertyNames(arr)); // ["0", "1", "2", "length"]
const obj6 = { 0: "a", 1: "b", 2: "c" };
console.log(Object.getOwnPropertyNames(obj6)); // ["0", "1", "2"]
function ParentClass() {
ParentClass.prototype.inhert = function () {
console.log(1234);
};
}
function SonClass() {
this.pro = 10;
this.methed = function () {};
}
SonClass.prototype = new ParentClass();
SonClass.prototype.newFun = function () {};
const sonClass = new SonClass();
console.log(Object.getOwnPropertyNames(sonClass)); // ['pro', 'methed'] 原型连上的属性不会被便利出来
/**
* Object.getOwnPropertySymbols()
* 返回一个包含给定对象所有自有的Symbol属性的数组,不包含原型连和继承上的Symbol属性
*/
const obj7 = {};
// 普通创建
const a = Symbol("a");
// 使用给定的描述创建
const b = Symbol.for("b");
obj7[a] = "aaaaa";
obj7[b] = "bbbbb";
const objSymbol = Object.getOwnPropertySymbols(obj7);
console.log(objSymbol); // [Symbol(a),Symbol(b)]
/**
* Object.getPrototypeOf()
* 返回该指定对象的原型属性,如果原型连的prototype有继承自其他的函数,也会被显示出来
*/
function getObj() {
this.par = 10;
}
getObj.prototype.pro = function () {
console.log(1234);
};
const getobj = new getObj();
function getchild() {
this.name = "sax";
this.age = 12;
}
getchild.prototype = new getObj();
getchild.prototype.sax = "Y";
const getx = new getchild();
console.log(getobj);
console.log(getx);
const propt = Object.getPrototypeOf(getx);
console.log(propt); // {par:10,sex:'y'} 还有getObj.prototype.pro的function函数 都属于原型链上的属性
/**
* Object.hasOwn()
* 如果指定对象自身有指定的属性,则调用object.hasOwn方法返回true,如果是继承的或者没有,则返回false
*/
const obj8 = {
a: 1,
b: 2,
};
Object.prototype.myname = "xxx";
console.log(obj8);
Object.hasOwn(obj8, "myname"); // false
function Par(name, sax) {
this.name = name;
this.sax = sax;
}
Par.prototype.newName = "yyyy";
const p = new Par();
Object.hasOwn(p, "name"); // true
Object.hasOwn(p, "newName"); // false
/**
* Object.prototype.hasOwnProperty() 一般写成 Object.hasOwnProperty()
* 他反回一个布尔值,表示对象自由属性(而不是继承的属性)中是否具有指定的属性
*/
const obj9 = { a: "123" };
obj9.hasOwnProperty("a"); // true
// 对象也是数组,可以检测对应的缩影是否存在
const fruits = ["Apple", "Banana", "Watermelon", "Orange"];
fruits.hasOwnProperty(3);
/**
* Object.prototype.isPrototypeOf(prototypeObject)
* isPrototypeOf() 方法用于检查一个对象是否存在于另一个对象的原型链中。
* object 是要检查的原型对象,prototypeObject 是要检查的原型链对象。
* 如果 object 是 prototypeObject 的原型或原型链中的一部分,那么 isPrototypeOf() 会返回 true。否则,它会返回 false。
*/
class Foo {}
class Bar extends Foo {}
class Baz extends Bar {}
const foo1 = new Foo();
const bar1 = new Bar();
const baz = new Baz();
// 原型链:
// foo1: Foo --> Object
// bar1: Bar --> Foo --> Object
// baz: Baz --> Bar --> Foo --> Object
console.log(Baz.prototype.isPrototypeOf(baz)); // true
console.log(Baz.prototype.isPrototypeOf(bar1)); // false
console.log(Baz.prototype.isPrototypeOf(foo1)); // false
console.log(Bar.prototype.isPrototypeOf(baz)); // true
console.log(Bar.prototype.isPrototypeOf(foo1)); // false
console.log(Foo.prototype.isPrototypeOf(baz)); // true
console.log(Foo.prototype.isPrototypeOf(bar1)); // true
console.log(Object.prototype.isPrototypeOf(baz)); // true
/**
* Object.preventExtensions()
* Object.preventExtensions() 静态方法可以防止新属性被添加到对象中(即防止该对象被扩展)。它还可以防止对象的原型被重新指定。
* Object.preventExtensions() 只能防止添加自有属性。但其对象类型的原型依然可以添加新的属性。
* 一旦将对象变为不可扩展的对象,就再也不能使其可扩展。
*
* Object.isExtensible() 判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)
*/
const objt = {};
const objt1 = Object.preventExtensions(objt);
objt === objt1; // true
// 字面量方式定义的对象默认是可扩展的。
const empty = {};
Object.isExtensible(empty); // true
// 可以将其改变为不可扩展的。
Object.preventExtensions(empty);
Object.isExtensible(empty); // false
/**
* Object.prototype.propertyIsEnumerable
* 方法返回一个布尔值,表示指定的属性是否是对象的可枚举自有属性
*/
const objt2 = {};
const arr2 = [];
objt2.prop = "是可枚举的";
arr2[0] = "是可枚举的";
objt2.propertyIsEnumerable("prop"); // true
arr2.propertyIsEnumerable(0); // true
/**
* Object.seal() Object.seal() 静态方法密封一个对象。密封一个对象会阻止其扩展并且使得现有属性不可配置。
* 密封对象有一组固定的属性:不能添加新属性、不能删除现有属性或更改其可枚举性和可配置性、不能重新分配其原型。
* 只要现有属性的值是可写的,它们仍然可以更改。seal() 返回传入的同一对象。
* Object.isSealed() 法判断一个对象是否被密封。
*/
const obj = {
prop() {},
foo: "bar",
};
// 可以添加新属性,可以更改或删除现有属性。
obj.foo = "baz";
obj.lumpy = "woof";
delete obj.prop;
const o = Object.seal(obj);
o === obj; // true
Object.isSealed(obj); // true
// 更改密封对象的属性值仍然有效。
obj.foo = "quux";
// 但不能将数据属性转换成访问者属性,反之亦然。
Object.defineProperty(obj, "foo", {
get() {
return "g";
},
}); // 抛出 TypeError
/**
* Object.setPrototypeOf(obj, prototype)
* Object.setPrototypeOf() 静态方法可以将一个指定对象的原型(即内部的 [[Prototype]] 属性)设置为另一个对象或者 null。
*/
const obj = {};
const parent = { foo: "bar" };
console.log(obj.foo); // undefined
Object.setPrototypeOf(obj, parent);
console.log(obj.foo); // bar
/**
* Object.prototype.toLocaleString()
* toLocaleString() 方法返回一个表示对象的字符串。该方法旨在由派生对象重写,以达到其特定于语言环境的目的。
*/
const obj = {
toString() {
return "My Object";
},
};
console.log(obj.toLocaleString()); // "My Object"
const testArray = [4, 7, 10];
const euroPrices = testArray.toLocaleString("fr", {
style: "currency",
currency: "EUR",
});
// "4,00 €,7,00 €,10,00 €"
JS里面Object对象上方法汇总
最新推荐文章于 2024-03-20 19:42:27 发布