前端开发之原型模式

介绍

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

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)]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/143802.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Redis-01 入门和十大数据类型

Redis支持两种持久化方式&#xff1a;RDB持久化和AOF持久化。 1.RDB持久化是将Redis的数据以快照的形式保存在磁盘上&#xff0c;可以手动触发或通过配置文件设置定时触发。RDB保存的是Redis在某个时间点上的数据快照&#xff0c;可以通过恢复RDB文件来恢复数据。 2.AOF持久化…

深蓝学院-- 量产自动驾驶中的规划控制算法 小鹏

文章目录 0. 前言1.发展现状2.行车功能中难点问题及解决思路问题1&#xff1a;车道居中辅助&#xff0c;画龙&#xff0c;蛇行问题。问题2&#xff1a;外界环境扰动以及传感器信息缺失下的横向控制难点问题3&#xff1a;大坡度平稳停车 3. 泊车功能中难点问题及解决思路问题1&a…

尚品汇-秒杀下单实现-页面轮询查询订单状态(五十三)

目录&#xff1a; &#xff08;1&#xff09;整合秒杀业务 &#xff08;2&#xff09;秒杀下单 &#xff08;3&#xff09;秒杀下单监听 &#xff08;4&#xff09;页面轮询接口 &#xff08;1&#xff09;整合秒杀业务 秒杀的主要目的就是获取一个下单资格&#xff0c;拥…

【iOS】——JSONModel源码

JSONModel用法 基本用法 将传入的字典转换成模型&#xff1a; 首先定义模型类&#xff1a; interface Person : JSONModel property (nonatomic, copy) NSString *name; property (nonatomic, copy) NSString *sex; property (nonatomic, assign) NSInteger age; end接…

索引的介绍

目录 1.索引的介绍 1.1 什么是索引 1.2 为什么要使用索引 2.索引应该选择哪种数据结构 3.MYSQL中的页 3.1为什么要使用页 3.2页文件头和页文件尾 3.3 页主体 3.3页目录 3.4数据页头 4.B在MYSQL索引中的应用 4.1计算三层树高的B树可以存放多少条记录 5.索引分类 5.1 主…

居中左右对齐且加粗的蓝色文本

//test.html <!DOCTYPE html> <html> <head> <title>我的网页</title> <link rel"stylesheet" href"styles.css"> </head> <body> <p class"left-text">这是居左对齐且加粗的…

Element走马灯组件循环播放两个页面是方向不一致

摘要&#xff1a;使用Carousel 走马灯循环播放同一类型的图片、文字等内容&#xff0c;会在循环内容为两组是出现下图 [1]中的现象。本文记录下如何解决 之前项目遇到过一次这个问题&#xff0c;由于indicator-position 指示器不用显示&#xff0c;则判断内容长度为2时&#xf…

springboot通过tomcat部署项目(包含jar、war两种方式,迄今为止全网最详细!2024更新..建议收藏,教学!万字长文!)

本博客参考的所有文章均已在结尾声明&#xff01;&#xff01;&#xff01; 在 Spring Boot 项目中&#xff0c;有两种常见的部署方式&#xff1a; 1、使用 Spring Boot 自带的 内置 Tomcat&#xff0c;将项目打包为 jar 并直接运行。 2、使用 外置 Tomcat&#xff0c;将项目打…

【电路笔记】-运算放大器比较器

运算放大器比较器 文章目录 运算放大器比较器1、概述2、表示2.1 同相比较器2.2 反相比较器3、临界点转换4、施密特触发器4.1 同相触发器4.2 反相触发器4.3 应用5、总结1、概述 在前面的大多数运算放大器文章中,电路都有一个到反相输入的反馈环路。 这种设计是最常见的,因为它…

海外社媒干货:Twitter的特点及运营策略

当你在海外社交媒体上运营&#xff0c;了解不同平台的特点和具体实践是非常重要的。本期让小编来为你介绍推特&#xff08;Twitter&#xff09;以及一些相关的运营干货&#xff1a; &#xff08;图片源于网络&#xff09; Twitter简介 推特是一家美国社交网络及微博客服务的公…

通过Python代码发送量化交易信号邮件通知

量化交易利用数学模型和计算机算法来分析市场数据,并生成交易信号,本文将介绍如何使用Python编写一个简单的脚本,通过发送邮件通知量化交易信号。 开启SMTP服务 首先要在发件箱的邮件设置中,将POP3/SMPT服务开启,记录下授权密码,在本地可通过此密码登录,注意有效期和保…

【C++ Primer Plus习题】16.9

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: #include <iostream> #include <ctime> #include <v…

6000 字掌握 Java IO 知识体系

“子谦&#xff0c;Java IO 也太上头了吧&#xff1f;”新兵蛋子小二向头顶很凉快的老韩抱怨道&#xff0c;“你瞧&#xff0c;我就按照传输方式对 IO 进行了一个简单的分类&#xff0c;就能搞出来这么多的玩意&#xff01;” 好久没搞过 IO 了&#xff0c;老王看到这幅思维导图…

LLM - 理解 多模态大语言模型(MLLM) 的 预训练(Pre-training) 与相关技术 (三)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/142167709 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 完备(F…

数字自然资源领域的实现路径

在数字化浪潮的推动下&#xff0c;自然资源的管理与利用正经历着前所未有的变革。本文将从测绘地理信息与遥感专业的角度&#xff0c;深度分析数字自然资源领域的实现路径。 1. 基础数据的数字化 数字自然资源的构建&#xff0c;首先需要实现基础数据的数字化。这包括地形地貌…

GUI编程16:图片按钮、单选框、多选框

视频链接&#xff1a;18、图片按钮、单选框、多选框_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1DJ411B75F?p18&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 1.图片按钮代码示例 package com.yundait.lesson05;import javax.swing.*; import java.awt.*; impo…

【Linux:共享内存】

共享内存的概念&#xff1a; 操作系统通过页表将共享内存的起始虚拟地址映射到当前进程的地址空间中共享内存是由需要通信的双方进程之一来创建但该资源并不属于创建它的进程&#xff0c;而属于操作系统 共享内存可以在系统中存在多份&#xff0c;供不同个数&#xff0c;不同进…

Google SERP API 对接说明

Google SERP API 对接说明 Google SERP&#xff08;Search Engine Results Page&#xff09;是用户在Google搜索引擎中输入查询后看到的结果页面。它显示自然搜索结果、广告、特色摘要、知识图谱以及图片、视频等多种内容&#xff0c;旨在为用户提供最相关的信息。 本文将详细…

心觉:成功学就像一把刀,有什么作用关键在于使用者(二)

Hi&#xff0c;我是心觉&#xff0c;与你一起玩转潜意识、脑波音乐和吸引力法则&#xff0c;轻松掌控自己的人生&#xff01; 挑战每日一省写作174/1000天 上一篇文章讲了成功学到底是个啥 是如何起作用的 为什么有些人觉得没有用&#xff1f; 今天我们再展开来剖析一下这…

运维监控专项学习笔记-id:0-需求场景、监控作用、监控能力

参考来源&#xff1a; 极客时间专栏-运维监控系统实战笔记&#xff0c;作者&#xff1a;秦晓辉 一、需求场景 学习监控知识&#xff0c;得先了解为什么&#xff0c;也就是监控是因何产生的&#xff0c;解决了什么问题&#xff0c;有哪些典型的方案&#xff0c;分别有什么优缺…