画布 1
Object
  遍历
    for...in：遍历对象
  工具
    keys()：返回所有key组成的数组
    values()：返回所有value组成的数组
    entries()：返回所有[key，value]的集合
    seal：密封一个对象，阻止其扩展
    freeze：冻结对象，阻止扩展，阻止修改value
    isSealed()：是否被密封
    isFrozen()：是否被冻结
    可以配合for...of进行遍历
    seal把对象固定为一种“模板”，属性不可变动，但值可以修改。freeze完全使对象不可变。
  拼接
    assign：拼接两个对象，属性相同则覆盖
  查
    hasOwnProperty(attr)：返回attr属性是否存在于obj自身
    attr in obj：返回attr属性是否存在于obj和obj的原型链
    判断 obj[“key”] 是否为undefined
    查询一个对象是否有某个属性。当然也可以通过遍历进行一一比对。注意使用in时原型链上的属性也在查找范围内，hasOwnProperty只查找自身。
  原型
    getPrototypeOf：返回指定对象的原型
    isPrototypeOf：是否为另一个对象的原型
    setPrototypeOf：设置对象的原型
    __proto__：返回它对应的原型对象
    prototype：用于定义通过该构造函数创建的实例的原型
let obj = { a: 1, b: 2, c: 3 };
for (const prop in obj) {
console.log("obj." + prop + " = " + obj[prop]);
}
// Output:
// "obj.a = 1"
// "obj.b = 2"
// "obj.c = 3"
如果不希望原型上的属性被遍历，可以结合hasOwnProperty：
const triangle = { a: 1, b: 2, c: 3 };
function ColoredTriangle() {
this.color = "red";
}
ColoredTriangle.prototype = triangle;
const obj = new ColoredTriangle();
for (const prop in obj) {
if (obj.hasOwnProperty(prop)) {
console.log(`obj.${prop} = ${obj[prop]}`);
}
}
// Output:
// "obj.color = red"
//打印所有key
const object1 = {
a: 'somestring',
b: 42,
c: false,
};
console.log(Object.keys(object1));
// Expected output: Array ["a", "b", "c"]
//打印所有value
const object1 = {
a: 'somestring',
b: 42,
c: false,
};
console.log(Object.values(object1));
// Expected output: Array ["somestring", 42, false]
//打印所有键值对
const object1 = {
a: 'somestring',
b: 42,
};
for (const [key, value] of Object.entries(object1)) {
console.log(`${key}: ${value}`);
}
// Expected output:
// "a: somestring"
// "b: 42"
//密封一个对象会阻止其扩展并且使得现有属性不可配置。密封对象有一组固定的属性：不能添加新属性、不能删除现有属性或更改其可枚举性和可配置性、不能重新分配其原型。只要现有属性的值是可写的，它们仍然可以更改。seal() 返回传入的同一对象。
const object1 = {
property1: 42,
};
Object.seal(object1);
object1.property1 = 33;
console.log(object1.property1);
// Expected output: 33 value可修改
delete object1.property1; // 不可删除属性（但不报错）
console.log(object1.property1);
// Expected output: 33
object1.aaa = '1';
console.log(object1.aaa);
// undefined 不可新增属性
const obj = {
prop: 42,
};
Object.freeze(obj);
obj.prop = 33;
// Throws an error in strict mode
console.log(obj.prop);
// Expected output: 42
const obj = {
a: 1,
b: 2,
c: 3
}
for (const key of Object.keys(obj)) {
console.log(key);
}
for (const value of Object.values(obj)) {
console.log(value);
}
for (const [key, value] of Object.entries(obj)) {
console.log(key, value);
}
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target);
// Expected output: Object { a: 1, b: 4, c: 5 }
//覆盖掉相同属性，合并对象
console.log(returnedTarget === target);
// Expected output: true
// 还是那个对象
const object1 = {};
object1.property1 = 42;
console.log(object1.hasOwnProperty('property1'));
// Expected output: true
console.log(object1.hasOwnProperty('toString'));
// Expected output: false
console.log(object1.hasOwnProperty('hasOwnProperty'));
// Expected output: false
// hasOwnProperty是其原型上的方法
// 注意：在一些写法严谨的项目中，被操作的对象的hasOwnProperty可能被重写，或者他是由Object.create(null)创建的空对象，没有hasOwnProperty方法。所以我们一般不会直接这样调用：
obj.hasOwnProperty("xxx");
而是：
Object.prototype.hasOwnProperty.call(obj，"xxx");
// 所以在支持 Object.hasOwn() 的浏览器中，建议使用 Object.hasOwn()，而非 hasOwnProperty()。这是mdn的描述：
//Object.hasOwn() 旨在取代 Object.prototype.hasOwnProperty()，因为它适用于使用 Object.create(null) 创建的对象，以及重写了继承的 hasOwnProperty() 方法的对象。尽管可以通过在外部对象上调用 Object.prototype.hasOwnProperty() 解决这些问题，但是 Object.hasOwn() 更加直观。
const car = { make: 'Honda', model: 'Accord', year: 1998 };
console.log('make' in car);
// Expected output: true
delete car.make;
if ('make' in car === false) {
car.make = 'Suzuki';
}
console.log(car.make);
// Expected output: "Suzuki"
const obj = {
a: 1,
b: 2
}
if (obj["a"]) {
console.log(obj.a);
}
if (obj["c"]) {
console.log(obj.c);
}
// 只打印1
var one = {x: 1};
one.__proto__ === Object.prototype // true
var obj = {};
var protoObj = { x: 10 };
obj.__proto__ = protoObj;
console.log(obj.x); // 输出 10，因为 obj 的原型是 protoObj
//__proto__ 是对象实例特有的属性，用于访问和修改实例的原型链
//注意：__proto__已被弃用。在新的标准中，推荐使用静态方法Object.getPrototypeOf()来代替，以避免__proto__的一些安全问题和隐患。
// prototype 是函数对象独有的属性，用于定义构造函数创建的实例对象的原型。当你创建一个函数时，它会自动拥有一个 prototype 属性，这个属性是一个对象，包含了构造函数的原型对象上的属性和方法。通过 new 关键字创建的实例对象会继承该 prototype 对象的属性和方法。
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log('Hello, ' + this.name + '!');
};
var person1 = new Person('John');
person1.sayHello(); // 输出 "Hello, John!"