当前位置: 首页 > news >正文

前端开发之原型模式

介绍

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

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

相关文章:

前端开发之原型模式

介绍 原型模式本质就是借用一个已有的实例做原型&#xff0c;在这原型基础上快速复制出一个和原型一样的一个对象。 class CloneDemo {name clone democlone(): CloneDemo {return new CloneDemo()} } 原型原型链 函数&#xff08;class&#xff09;都有显示原型 prototyp…...

分布式缓存服务Redis版解析与配置方式

一、Redis分布式缓存服务概述 Redis是一款高性能的键值对&#xff08;Key-Value&#xff09;存储系统&#xff0c;通常用作分布式缓存服务。它基于内存运行&#xff0c;支持丰富的数据类型&#xff0c;并具备高并发、低延迟的特点&#xff0c;非常适合用于缓存需要频繁访问的数…...

WordPress建站钩子函数及使用

目录 前言&#xff1a; 使用场景&#xff1a; 一、常用的wordpress钩子&#xff08;动作钩子、过滤器钩子&#xff09; 1、动作钩子&#xff08;Action Hooks&#xff09; 2、过滤器钩子&#xff08;Filter Hooks&#xff09; 二、常用钩子示例 1、添加自定义 CSS 和 JS…...

Qt 模型视图(二):模型类QAbstractItemModel

文章目录 Qt 模型视图(二)&#xff1a;模型类QAbstractItemModel1.基本概念1.1.模型的基本结构1.2.模型索引1.3.行号和列号1.4.父项1.5.项的角色1.6.总结 Qt 模型视图(二)&#xff1a;模型类QAbstractItemModel ​ 模型/视图结构是一种将数据存储和界面展示分离的编程方法。模…...

算法打卡 Day41(动态规划)-理论基础 + 斐波那契数 + 爬楼梯 + 使用最小花费爬楼梯

文章目录 理论基础Leetcode 509-斐波那契数题目描述解题思路 Leetcode 70-爬楼梯题目描述解题思路 Leetcode 746-用最小花费爬楼梯题目描述解题思路 理论基础 动态规划&#xff0c;简称 DP&#xff0c;其中的每一个状态一定是由上一个状态推导出来的&#xff0c;而贪心算法没有…...

鸿蒙环境服务端签名直传文件到OSS

本文介绍如何在鸿蒙环境下将文件上传到OSS。 背景信息 鸿蒙环境是当下比较流行的操作环境&#xff0c;与服务端签名直传的原理类似&#xff0c;鸿蒙环境上传文件到OSS是利用OSS提供的PutObject接口来实现文件上传到OSS。关于PutObject的详细介绍&#xff0c;请参见PutObject。…...

计算机毕业设计Python+Flask微博情感分析 微博舆情预测 微博爬虫 微博大数据 舆情分析系统 大数据毕业设计 NLP文本分类 机器学习 深度学习 AI

首先安装需要的python库&#xff0c; 安装完之后利用navicat导入数据库文件bili100.sql到mysql中&#xff0c; 再在pycharm编译器中连接mysql数据库&#xff0c;并在设置文件中将密码修改成你的数据库密码。最后运行app.py&#xff0c;打开链接&#xff0c;即可运行。 B站爬虫数…...

solidwork剪裁实体

之前是这样&#xff1a; 效果如下&#xff1a;...

Junit与Spring Test简单使用

Junit与Spring Test简单使用 Junit5简介Junit5 注解Junit5与Spring结合 差异概览MockingMockBeanSpyBeanDemo 注意事项 又要写测试代码了&#xff0c;总结记录一下。 Junit5简介 与单一模块设计的Junit4不同,Junit5引入了模块化架构,由三个主要子项目组成&#xff1a; JUnit Pl…...

Vxe UI vue vxe-table 实现自适应列宽,根据内容自适应列的宽度

Vxe UI vue vxe-table 实现自适应列宽&#xff0c;根据内容自适应列的宽度 之前老版本是通过计算字符数量&#xff0c;然后给动态给每一列设置宽度&#xff0c;不仅麻烦&#xff0c;还不好复用。 看了 API 发现 v4.7 和 v3.9 版本已经直接就能支持了&#xff0c;只需加上 widt…...

document.visibilityState 监听浏览器最小化

1.document.hidden&#xff1a; 表示页面是否隐藏的布尔值。页面隐藏包括 页面在后台标签页中 或者 浏览器最小化 &#xff08;注意&#xff0c;页面被其他软件遮盖并不算隐藏&#xff0c;比如打开的 sublime 遮住了浏览器&#xff09;。 2.document.visibilityState&#xff…...

前端框架对比和选择

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言&#xff1a; 前端框架选择是前端开发中的关键决策&#xff0c;因为它影响项目的开发效率、维护成本和可扩展性。当前&#xff0c;最流行的前端框架主要包括 React、Vue 和 Angular。它们各有优劣&#xff0c;适用于不同…...

Linux 进程2

环境变量 再Linux操作系统中一切皆文件&#xff0c;这个环境变量自然也是一个文件&#xff0c;它的作用是辅助我们使用操作系统还可以辨识我们是什么用户(一般用户&#xff0c;root用户)。 env是读取完整环境变量的指令&#xff0c;里面记录了许多我登录操作系统所用的用户的信…...

WPF入门教学六 Grid布局进阶

在WPF&#xff08;Windows Presentation Foundation&#xff09;中&#xff0c;Grid布局是一种非常强大且灵活的布局控件&#xff0c;它允许你创建复杂的用户界面。以下是Grid布局的一些进阶技巧和教学&#xff1a; 一、基本概念回顾 Grid定义&#xff1a;Grid是一个用于布局…...

while循环及简单案例

//循环是流程控制中的一个重要分支 //流程控制 条件判断 循环 逻辑处理 //循环的目的和意义 //循环的目的是为了执行一块代码 //循环的意义是为了简化代码。增加代码的复用性 /* //例如输出0-100的数…...

电子看板实时监控数据可视化助力工厂精细化管理

在当今竞争激烈的制造业领域&#xff0c;工厂的精细化管理成为提高竞争力的关键。而电子看板实时监控数据可视化作为一种先进的管理工具&#xff0c;正为工厂的精细化管理带来巨大的助力。 一、工厂精细化管理的挑战 随着市场需求的不断变化和客户对产品质量要求的日益提高&am…...

邮储银行:面向金融行业的移动应用安全风险监测案例

本项目通过在移动应用中植入威胁情报探针并结合网络镜像流量方式,利用应用运行过程中设备、系统、应用、行为四个维度数据,将其与设备的关键因子关联生成唯一的移动设备指纹;对手机银行等应用资产进行资产台账梳理;结合服务端大数据分析平台的各种模型规则分析,实时监测移…...

ARMxy车辆数据采集Linux智能控制器

在当今科技日新月异的时代&#xff0c;高效智能的边缘计算设备在众多领域发挥着关键作用。我们的 ARM 边缘计算机&#xff0c;凭借其卓越的性能和广泛的适用性&#xff0c;成为车队管理智能化的核心力量。 一、强大硬件配置&#xff0c;完美适配车队管理需求 ARM 边缘计算机支…...

7.Java高级编程 多线程

Java高级编程 多线程 文章目录 Java高级编程 多线程一、进程与线程查看线程 二、线程创建方式三、线程状态四、线程常用方法五、线程安全 一、进程与线程 一个程序有一个进程 一个进程包含多个线程&#xff08;必须有一个主线程&#xff09; 并发&#xff1a; 在同一时刻&a…...

MT8370|MTK8370(Genio 510 )安卓核心板参数介绍

MTK Genio 510 (MT8370)安卓核心板是一款极为先进的高性能平台&#xff0c;专为满足边缘处理、先进多媒体功能及全面的连接需求而设计&#xff0c;适用于多种人工智能(AI)和物联网(IoT)应用场景。它具备多个高分辨率摄像头支持和可联网触摸屏显示&#xff0c;适用于使用多任务高…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录&#xff0c;不允许匿名访问&#xff0c;kefu只能访问/data/kefu目录&#xff0c;不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...