目录
原型链:obj.__proto__===Obj.prototype
null:唯一不从 Object.prototype 继承的对象(防止原型污染攻击)
Object.prototype 的原型始终为 null 且不可更改
Function.prototype === Function.__proto__; // true
Function本身也是函数,所以 Function是Function的实例
Object静态方法/Object.prototype.方法.call(obj,...)
instanceof代替Obj.prototype.isPrototypeOf(obj)
Obj.get/setPrototypeOf(obj)代替obj._ _ proto _ _
Obj.hasOwn(obj, prop)代替Obj.prototype.hasOwnProperty()
Object.assign(target, ...sources)返回修改后的同地址的obj(target)
对象内容,而非地址Object.assign({}, obj)浅拷贝一层
Object.is(val0, val1):NaN等,±0不等
Obj.create(obj[,props]) 以实例作为原型,创建新对象
Object.defineProperties(obj,props)
enumerable:默认为 false,不可枚举(自有属性)
Object.prototype.propertyIsEnumerable(prop)
等价于 Object.getOwnPropertyDescriptor(obj, prop)?.enumerable ?? false
props+symbol:propertyDescripts
js判断数据类型、toString和valueOf区别,类型转换、不同类型间的运算、判断相等

原型:提供继承者共享属性/方法的对象
引用类型:__proto__(隐式原型)属性,属性值是对象函数:prototype(原型)属性,属性值是对象
- const o = {
- a: 1,
- b: 2,
- // __proto__ 设置了 [[Prototype]]。它在这里被指定为另一个对象字面量。
- __proto__: {
- b: 3,
- c: 4,
- __proto__: {
- d: 5,
- },
- },
- };
-
- // { a: 1, b: 2 } ---> { b: 3, c: 4 } ---> { d: 5 } ---> Object.prototype ---> null
-
- console.log(o.d); // 5
Object.prototype 继承的对象(防止原型污染攻击)- const user = {};
-
- // 恶意脚本:
- Object.prototype.authenticated = true;
-
- // 意外允许未经身份验证的用户通过
- if (user.authenticated) {
- // 访问机密数据
- }
- const ages = { alice: 18, bob: 27 };
-
- function hasPerson(name) {
- return name in ages;
- }
-
- function getAge(name) {
- return ages[name];
- }
-
- hasPerson("hasOwnProperty"); // true
- getAge("toString"); // [Function: toString]
由于存在 Object.prototype 属性,会导致一些错误:
- const ages = Object.create(null, {
- alice: { value: 18, enumerable: true },
- bob: { value: 27, enumerable: true },
- });
-
- hasPerson("hasOwnProperty"); // false
- getAge("toString"); // undefined
Object.prototype 的原型始终为 null 且不可更改- Function.prototype.before=function(beforefn){
- return ()=>{
- beforefn.apply(this,arguments)
- return this.apply(this,arguments)
- }
- }
- Function.prototype.after=function(afterfn){
- return ()=>{
- var res=this.apply(this,arguments)
- afterfn.apply(this,arguments)
- return res;
- }
- }
-
- var func=function(){
- console.log(1)
- }.before(function(){
- console.log(2)
- }).after(function(){
- console.log(3)
- })
- func()//213
应该避免调用任何 Object.prototype 方法,特别是那些不打算多态化的方法(即只有其初始行为是合理的,且无法被任何继承的对象以合理的方式重写),而尽量用Object的静态方法
Object.prototype.方法.call(obj,...)如果不存在语义上等价的静态方法,或者你真的想使用 Object.prototype 方法,你应该通过 call()直接在目标对象上调用 Object.prototype 方法,以防止因目标对象上原有方法被重写而产生意外的结果。
- const obj = {
- foo: 1,
- // 如果可能的话,你不应该在自己的对象上定义这样的方法,
- // 但是如果你从外部输入接收对象,可能无法防止这种情况的发生
- propertyIsEnumerable() {
- return false;
- },
- };
-
- obj.propertyIsEnumerable("foo"); // false;预期外的结果
- Object.prototype.propertyIsEnumerable.call(obj, "foo"); // true;预期的结果
hasOwnProperty()在支持 Object.hasOwn 的浏览器中,建议使用 Object.hasOwn(),而非
hasOwnProperty()。1.与重写的hasOwnProperty一起使用
const foo = { hasOwnProperty() { return false; }, bar: "The dragons be out of office", }; if (Object.hasOwn(foo, "bar")) { console.log(foo.bar); //true——重新实现 hasOwnProperty() 不会影响 Object }2.测试使用 Object.create(null) 创建的对象。这些对象不会继承自
Object.prototype,因此hasOwnProperty()方法是无法访问的。
const foo = Object.create(null); foo.prop = "exists"; if (Object.hasOwn(foo, "prop")) { console.log(foo.prop); //true——无论对象是如何创建的,它都可以运行。 }
- 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
- let obj1 = { key: 'value' };
- let obj2 = Object.assign({}, obj1); // 创建obj1的浅拷贝
-
- obj1.key = 'new value';
- console.log(obj2.key); // 输出: 'value'
严格值相等
obj[,props]) 以实例作为原型,创建新对象props等价于Object.defineProperties的props
Object.defineProperties(obj,props)- const object1 = {};
-
- Object.defineProperties(object1, {
- property1: {
- value: 42,
- writable: true,
- },
- property2: {},
- });
-
- console.log(object1.property1);
- // Expected output: 42
false,不可枚举(自有属性)大多数内置属性默认情况下是不可枚举的
??是空值合并操作符(Nullish Coalescing Operator)
Object.keys()/values()运算符试图删除的属性不存在,那么 delete 将不会起任何作用,但仍会返回 true
in obj- const trees = ["redwood", "bay", "cedar", "oak", "maple"];
- trees[3] = undefined;
- console.log(3 in trees); // true
Object.getOwnPropertyDescriptor(obj, prop)
