对象补充-原型和函数原型-创建对象

defineProperties可以定义多个属性描述符

var obj = {
    // 私有属性(js里面是没有严格意义的私有属性)
    _age: 18,
    _eat: function() {}
}

Object.defineProperties(obj, {
    name: {
        configurable: true,
        enumerable: true,
        writable: true,
        value: "why"
    },
    age: {
        configurable: false,
        enumerable: false,
        get: function () {
            return this._age
        },
        set: function (value) {
            this._age = value
        }
    }
})
console.log(obj)
// 

对象方法补充

1、获取对象的属性描述符

  • getOwnPropertyDescriptor
  • getOwnPropertyDescriptors
var obj = {
    // 私有属性(js里面是没有严格意义的私有属性)
    _age: 18,
    _eat: function() {}
}

Object.defineProperties(obj, {
    name: {
        configurable: true,
        enumerable: true,
        writable: true,
        value: "why"
    },
    age: {
        configurable: false,
        enumerable: false,
        get: function () {
            return this._age
        },
        set: function (value) {
            this._age = value
        }
    }
})
// 获取某一个特定属性的属性描述符
console.log(Object.getOwnPropertyDescriptor(obj,'name'))
// 获取对象的所有属性描述符
console.log(Object.getOwnPropertyDescriptors(obj))

执行结果:

2、禁止对象扩展新属性:preventExtensions

3、禁止对象配置/删除里的属性

var obj = {
    name: 'why',
    age: 8
}

// 禁止对象继续添加新的属性
Object.preventExtensions(obj)

obj.height = 1.88
obj.address = "成都市"

console.log(obj)

Object.seal(obj)

delete obj.name

console.log(obj)

分别不注释Object.seal(obj)和注释Object.seal(obj)的结果

 4、让属性不可以修改

var obj = {
    name: 'why',
    age: 8
}

// 让属性不可以修改(writable:false)
Object.freeze(obj)

obj.name = 'kobe'
console.log(obj.name)

执行结果

创建多个对象的方案

工厂模式

  1. 工厂模式其实是一种常见的设计模式
  2. 通常我们会有一个工厂方法,通过该工厂方法我们可以产生想要的对象
// 工厂模式: 工厂函数
function createPerson(name, age, height, address) {
    var p = {}
    p.name = name
    p.age = age
    p.height = height
    p.address = address
    p.eating = function () {
        console.log(this.name + "在吃东西~")
    },
    p.running = function () {
        console.log(this.name + "在跑步!")
    }
    return p
}

var p1 = createPerson('张三', 18, 1.78, '北京市')
var p2 = createPerson('李四', 23, 1.88, '成都市')
var p3 = createPerson('王麻子', 28, 1.98, '重庆市')

// 工厂模式的缺点(获取不到对象最真实的类型)
console.log(p1, p2, p3)

构造函数

// 构造函数
function person(name, age, height, address) {
    this.name = name
    this.age = age
    this.height = height
    this.address = address
    this.eating = function () {
        console.log(this.name + "在吃东西~")
    },
    this.running = function () {
        console.log(this.name + "在跑步!")
    }
}

var p1 = new person('张三', 18, 1.78, '北京市')
console.log(p1)

规范:构造函数的首字母一般是大写

原型的概念

// 我们每一个对象都有一个[[prototype]],这个属性可以称之为对象的原型(隐式原型)

var obj = { name: 'why'}  // [[prototype]]
var info = {}  // [[prototype]]

// 1、解释原型的概念和看一下原型
// 早期的ECMA是没有规范如何查看[[prototype]]

// 给对象中提供了一个属性,可以让我们查看一下这个原型对象(浏览器提供)
// __proto__

// console.log(obj.__proto__)
// console.log(info.__proto__)

var obj = { name: 'why', __proto__: {}}

// ES5之后提供的Object.getPrototypeOf

// console.log(Object.getPrototypeOf(obj))


// 2、原型有什么用
// 当我们从一个对象中获取某一个属性时,它会触发[[get]]操作
// 1、在当前对象中去查找对应的属性,如果找到就直接使用
// 2、如果没有找到,那么会沿着它的原型去查找[[prototype]]
// obj.age = 18
obj.__proto__.age = 18

console.log(obj.age)

Person构造函数原型内存图

函数原型上的属性-constructor

赋值为新的对象

function foo() {
    
}

// foo.prototype这个对象中有一个constructor的属性
// console.log(foo.prototype)
// console.log(Object.getOwnPropertyDescriptor(foo.prototype))

// Object.defineProperty(foo.prototype, 'constructor', {
//     enumerable: true,
//     configurable: true,
//     writable: true,
//     value: "哈哈哈哈"
// })

// console.log(foo.prototype)

// prototype.constructor = 构造函数本身

// console.log(foo.prototype.constructor)  // [Function: foo]
// console.log(foo.prototype.constructor.name)

// console.log(foo.prototype.constructor.prototype.constructor.prototype.constructor)

// 2. 我们也可以添加自己的属性
// foo.prototype.name = "why"
// foo.prototype.age = 18
// foo.prototype.height = 180
// foo.prototype.eating = function () {
    
// }

// var f1 = new foo()
// console.log(f1.name, f1.age)

// 3.直接修改整个prototype
foo.prototype =  {
    // constructor: foo,
    name: "why",
    age: 18,
    height: 180
}

var f1 = new foo()
console.log(f1.name, f1.age, f1.height)

// 真实开发中我们通过Object.defineProperty方式添加constructor
Object.defineProperty(foo.prototype, 'constructor', {
    enumerable: true,
    configurable: true,
    writable: true,
    value: foo
})

创建对象方案-原型和构造函数

function Person(name, age, height, address) {
    this.name = name
    this.age = age
    this.height = height
    this.address = address
}

Person.prototype.eating = function() {
    console.log(this.name + "在吃东西~")
}

Person.prototype.running = function() {
    console.log(this.name + "在跑步~")
}


var p1 = new Person('why', 18, 1.88, '北京市')
var p2 = new Person('kobe', 20, 1.98, '洛杉矶市')

p1.eating()
p2.running()

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis快速上手篇七(集群-六台虚拟机)

Redis集群 主从复制的场景无法吗满足主机单点故障时需要引入集群配置 一般数据库要处理的读请求远大于写请求 ,针对这种情况,我们优化数据库可以采用读写分离的策略。我们可以部 署一台主服务器主要用来处理写请求,部署多台从服务器 &#…

C#学习相关系列之多线程---ConfigureAwait的用法

一、ConfigureAwait的作用 ConfigureAwait方法是Task类中的一个实例方法,它用于配置任务的运行上下文。运行上下文指的是任务在执行期间所处的环境,包括线程、同步上下文等。ConfigureAwait方法接受一个布尔值参数,用于决定是否捕获上下文。当…

导弹拦截(最大不上升 或 不下降子序列,dp)

算法分析: 1.求最长子序列 1.每次输入时,计算每个元素对应的序列的长度 1.向前遍历找大于当前元素的数 2.若之前元素对应长度1 大于当前长度,更新当前长度 2.若当前元素对应长度 大于最大长度,更新最大长度 2.dilworth定理 故需…

HarmonyOS开发:NodeJs脚本实现组件化动态切换

前言 上篇文章,我们使用NodeJs脚本完成了HarmonyOS项目的组件化运行,但是由于脚本是基于4.0.0.400版本的DevEco Studio开发的,可能在配置文件的修改上有些许差距,那么遇到这种情况怎么办,一种是再写一套针对性的脚本文…

系列四十二、Spring的事务传播行为案例演示(二)#REQUIRED

一、演示Spring的默认传播行为(REQUIRED) 1.1、运行之前表中的数据 1.2、StockServiceImpl /*** Author : 一叶浮萍归大海* Date: 2023/10/30 15:43* Description:*/ Service(value "stockServiceREQUIRED") public class StockServiceImpl…

MSQL系列(十) Mysql实战-Join驱动表和被驱动表如何区分

Mysql实战-Join驱动表和被驱动表如何区分 前面我们讲解了Mysql的查询连接Join的算法原理, 我发现大家都知道小表驱动大表,要让小表作为驱动表, 现在有2个问题 查询多表, 到底哪个是驱动表?哪个是被驱动表, 如何区分?索引如何优化,到底是加在驱动表上,还是被驱动表上? &…

二维数组如何更快地遍历

二维数组如何更快地遍历 有时候,我们会发现,自己的代码和别人的代码几乎一模一样,但运行时间差了很多,别人是 AC \text{AC} AC,你是 TLE \text{TLE} TLE,这是为什么呢? 一个可能的原因是数组的…

2023高德地图poi资源下载

全国8千万地图poi地图数据:含名称、地址、电话、省份、城市、区县、经纬度、电话等信息

第五章 I/O管理 六、I/O核心子系统

目录 一、核心子系统 1、I/O调度 2、设备保护 二、假脱机技术 1、脱机: 2、假脱机(SPOOLing技术): 3、应用: 1.独占式设备: 2.共享设备: 4、共享打印机原理分析 三、总结 一、核心子系…

metaRTC集成flutter ui demo编译指南

概要 Flutter是由Google开发的开源UI工具包,用于构建跨平台应用程序,支持linux/windows/mac/android/ios等操作系统。 metaRTC新增flutter demo,支持linux/windows/mac/android/ios操作系统,此demo在ubuntu桌面环境下测试成功。…

Jenkins项目部署

使用jenkins部署项目 简易版使用jenkins部署项目 将war包部署到tomcat中 将已有的war包部署到tomcat中(jenkins与tomcat在同一台主机) 点击Jenkins主页的新建任务 输入任务名称 选择构建一个自由风格的软件项目后点击确定 在构建内添加构建步骤,选择执行shell 输入…

时间序列预测大模型-TimeGPT

时间序列预测领域正在经历一个非常激动人心的时期。仅在过去的三年里,我们就看到了许多重要的贡献,例如N-BEATS、N-HiTS、PatchTST和TimesNet。 与此同时,大型语言模型 (LLM)最近在 ChatGPT 等应用程序中广受欢迎,因为它们无需进…

自动化项目实战 [个人博客系统]

自动化博客项目 用户注册登录验证效验个人博客列表页博客数量不为 0 博客系统主页写博客 我的博客列表页效验 刚发布的博客的标题和时间查看 文章详情页删除文章效验第一篇博客 不是 "自动化测试" 注销退出到登录页面,用户名密码为空 用户注册 Order(1)Parameterized…

Spring Cloud之API网关(Zuul)

目录 Zuul 简介 功能 工作流程 搭建 1.引入依赖 2.添加注解 3.路由转发 4.测试 实现原理 EnableZuulProxy注解 ZuulServlet FilterProcessor Zuul内置过滤器 常用配置 Zuul 简介 zuul是SpringCloud子项目的核心组件之一,可以作为微服务架构中的API网…

【C】C语言文件操作

1.为什么使用文件 我们前面学习结构体时,写通讯录的程序,当通讯录运行起来的时候,可以给通讯录中增加、删除数据,此时数据是存放在内存中,当程序退出的时候,通讯录中的数据自然就不存在了,等下…

超全整理,Jmeter性能测试-脚本error报错排查/分布式压测(详全)

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 性能脚本error报错…

域名系统 DNS

DNS 概述 域名系统 DNS(Domain Name System)是因特网使用的命名系统,用来把便于人们使用的机器名字转换成为 IP 地址。域名系统其实就是名字系统。为什么不叫“名字”而叫“域名”呢?这是因为在这种因特网的命名系统中使用了许多的“域(domain)”&#x…

S5PV210裸机(九):ADC

本文主要探讨210的ADC相关知识。 ADC ADC:模数转换(模拟信号转数字信号) 量程:模拟电压信号范围(210为0~3.3V) 精度:若10二进制位来表示精度(210为10位或12位),量…

线性代数 第三章 向量

一、运算 加法、数乘、内积 施密特正交化 二、线性表出 概念:如果,则称可由线性表出(k不要求不全为0) 判定: 非齐次线性方程组有解无关,相关 如果两个向量组可以互相线性表出,则称这两个…

Xilinx 7 系列 1.8V LVDS 和 2.5V LVDS 信号之间的 LVDS 兼容性

如果通过LVDS进行接口,可以按照以程图中的步骤操作,以确保满足正确使用LVDS的所有要求。 40191 - 7 系列 - 1.8V LVDS 和 2.5V LVDS 信号之间的 LVDS 兼容性 与LVDS兼容驱动器和接收器连接时,7系列LVDS和LVDS_25输入和输出应该不存在兼容性问…
最新文章