您的位置:首页 > 科技 > 能源 > 快速开发平台开源_昆明网络营销公司哪家好_软文代写兼职_福州seo扣费

快速开发平台开源_昆明网络营销公司哪家好_软文代写兼职_福州seo扣费

2024/12/23 9:01:22 来源:https://blog.csdn.net/weijia_kmy/article/details/142369020  浏览:    关键词:快速开发平台开源_昆明网络营销公司哪家好_软文代写兼职_福州seo扣费
快速开发平台开源_昆明网络营销公司哪家好_软文代写兼职_福州seo扣费

介绍

原型模式本质就是借用一个已有的实例做原型,在这原型基础上快速复制出一个和原型一样的一个对象。

class CloneDemo {name = 'clone demo'clone(): CloneDemo {return  new CloneDemo()}
}

原型原型链

  1. 函数(class)都有显示原型 prototype
  2. 对象都有隐式原型__proto__
  3. 对象__proto__指向其构造函数的 prototype

原型链:当试图访问一个对象的属性或方法时,如果对象本身没有定义这个属性或方法,JavaScript引擎就会沿着这个对象的原型链向上查找,直到找到或者到达原型链的末端。

class 是 function 的语法糖

class Foo {}
const f1 = new Foo()
console.log(f1.__proto__ === Foo.prototype) // true

 场景

const obj = {foo() {console.log("foo");},
};
const obj2 = Object.create(obj);
obj2.foo(); // foo
console.log(obj2.__proto__ === obj); // true

Object.create(null)、Object.create({})和 {} 的区别?

const obj1 = Object.create(null)
console.log("obj1", obj1)const obj2 = {}
console.log("obj2", obj2)const obj3 = Object.create(Object.prototype)
console.log("obj3", obj3)const obj4 = Object.create({})
console.log("obj4", obj4)

如上图结果:

  1. Object.create(null) 创建的对象是一个空对象,在该对象上没有继承 Object.prototype 原型链上的属性或者方法。也就是没有任何属性,显示 No properties 。
  2. Object.create(Object.prototype) 和 {} 创建的一模一样。
  3. Object.create({}) 相比于 {} 多了一层 proto 嵌套。

对象属性描述符

const obj = { x: 100 }; // 各项属性默认都是 true, 但是通过 defineProperty 定义的各项属性都是falseconst gopd = Object.getOwnPropertyDescriptor(obj, "x");
console.log(gopd); // {value: 100, writable: true, enumerable: true, configurable: true}    Object.defineProperty(obj, "y", {value: 200,writable: false,
});
console.log(obj); // {x: 100, y: 200}
obj.y = 201;
console.log(obj.y); // 200

(1)value

它是用来定义属性值,如果没有value,则看不到对象属性值,但可以通过get set 来操作属性值。

const obj = { x: 100 };let y = 200;
Object.defineProperty(obj, "y", {get() {return y;},set(newValue) {y = newValue;},
});
console.log(obj); // {x: 100} 这里没有 y
console.log(obj.y); // 200 但是这里又能打印出 y
obj.y = 201;
console.log(obj.y); // 201
console.log(obj); // {x: 100} 还是没有 y
const gopd = Object.getOwnPropertyDescriptor(obj, "y");
console.log(gopd); // {enumerable: false, configurable: false, get: ƒ, set: ƒ} 确实没有 value,所以没有显示 y

(2)configurable

是否可以 delete 删除,并重新定义

是否可以修改其他属性描述符

是否可以修改get set

const obj = { x: 100 };Object.defineProperty(obj, "y", {value: 200,configurable: false
});Object.defineProperty(obj, "z", {value: 300,configurable: true
});
console.log(obj) // {x: 100, y: 200, z: 300}
console.log(delete obj.y) // false// Object.defineProperty(obj, "y", {
//     value: 201,
//     configurable: false
// });
// Uncaught TypeError: Cannot redefine property: yObject.defineProperty(obj, "z", {value: 301,configurable: true
});
console.log(obj) // {x: 100, y: 200, z: 301}

(3)writable

属性值是否可被修改。对比Object.freeze()"冻结"、Object.seal()"密封"

const obj = { x: 100 };
Object.defineProperty(obj, "y", {value: 200,writable: false,
});
obj.x = 101;
console.log(obj); // {x: 101, y: 200}
obj.y = 201;
console.log(obj); // {x: 101, y: 200} 无法修改 y// Object.freeze() "冻结":现有属性不可被修改;2.不可添加新属性
const obj = { x: 100, y: 200 };
Object.freeze(obj);
console.log(Object.getOwnPropertyDescriptor(obj, 'x')) // {value: 100, writable: false, enumerable: true, configurable: false}
console.log(Object.isFrozen(obj)); // true
obj.x = 101; // Uncaught TypeError: Cannot assign to read only property 'x' of object '#<Object>'
obj.z = 300; // Uncaught TypeError: Cannot add property z, object is not extensible// Object.seal()"密封":1.现有属性可以被修改;2.不可添加新属性
const obj = { x: 100, y: 200 };
Object.seal(obj);
obj.x = 101;
console.log(obj.x); // 101 修改成功
console.log(Object.getOwnPropertyDescriptor(obj, 'x')) // {value: 101, writable: true, enumerable: true, configurable: false}
console.log(Object.isSealed(obj)); // true
obj.z = 300; // Uncaught TypeError: Cannot add property z, object is not extensible

(4)enumerable

是否可以通过for in 遍历。

const obj = { x: 100 };
Object.defineProperty(obj, "y", {value: 200,enumerable: false,
});
Object.defineProperty(obj, "z", {value: 300,enumerable: true,
});
for (const key in obj) {console.log(key);
}
// x z
console.log("x" in obj); // true
console.log("y" in obj); // true
console.log("z" in obj); // true

原型属性的 enumerable:在以前,for in 可以遍历出原型属性。现在全根据 enumerable 来遍历。为什么没有原型属性了呢?

console.log(Object.getOwnPropertyDescriptor(obj.__proto__, 'toString')) 
// {writable: true, enumerable: false, configurable: true, value: ƒ}

可见 enumerable 是 false,所以再用for in 遍历就遍历不出来了。之前是怎么做的呢?之前有一个方法是 hasOwnProperty 来判断是否原型属性。

console.log(obj.hasOwnProperty("x")); // true
console.log(obj.hasOwnProperty("toString")); // false

如何遍历Symbol 属性?

const a = Symbol("a");
const obj = { [a]: 10, b: 20 };console.log(Object.getOwnPropertyDescriptor(obj, a)); // {value: 10, writable: true, enumerable: true, configurable: true}for (const key in obj) {console.log(key);
}
// b  说明 for in 的限制不光有 enumerable,还有 Symbol 类型。
// 那么如何把Symbol遍历出来呢?
console.log(Object.keys(obj)); // ['b']
console.log(Object.getOwnPropertyNames(obj)); // ['b']
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(a)]
console.log(Reflect.ownKeys(obj)); // ['b', Symbol(a)]

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com