首页 > 其他分享 >理解对象

理解对象

时间:2023-04-30 23:35:51浏览次数:34  
标签:console log 对象 理解 原型 构造函数 name

目录

1. 理解对象

1.1 属性的类型

​ ESMA-262 使用一些内部特性来描述属性的特征。 这些特性是由为JavaScript实现引擎的规范定义的, 因此, 开发者不能再JavaScript 中直接访问这些特性

​ 为了将某个特性标识为内部特性,规范会用两个中括号把特性的名称括起来, 比如 [[Enumerable]]

ECMAScript 中将属性分为了两种:

  1. 数据属性
  2. 访问器属性

1.1.1 数据属性 CEWV

数据属性包含了一个保存数据值的位置。 值会从这个位置读取,也会写入到这个位置。 数据属性有四个特性描述它们的行为。

  1. [[Configurable]] :
    1. 属性是否可以通过 delete 删除并重新定义;
    2. 是否可以修改它的特性;
    3. 是否可以把它改为 访问器属性
    4. 默认值为 true
  2. [[Enumerable]] :
    1. 属性是否可以通过for-in 循环返回。
    2. 默认值为 true
  3. [[Writable]] :
    1. 属性的值是否可以被修改;
    2. 默认值为 true
  4. [[Value]] :
    1. 属性实际的值
    2. 默认值为 undefined

当我们创建一个对象时,如:

let person = {
    name: "Nicholas"
};

属性name 的数据属性 [[Configurable]][[Enumerable]][[Writable]] 都会被设置为 true, 而 [[Value]] 特性会被设置为指定的值,即 "Nicholas"

1.1.1.2 修改与访问 数据属性
1.1.1.2.1 修改属性的默认特性

Object 有两个静态方法用于修改 数据属性:

  1. Object.defineProperty()
  2. Object.defineProperties()

Object.defineProperty()

该方法用于修改对象单个值的数据属性,其语法格式如下:

Object.defineProperty(属性的对象,属性的名称,描述符对象({CEWV}))

示例:

let person = {};
Object.defineProperty(person, "name", {
    Writable: false,
    value: "Nicholas"
});

console.log(person.name);	//	"Nicholas"
person.name = "Greg";
console.log(person.name); //	"Nicholas"

⚠️ 严格模式下,尝试修改只读属性的值会抛出错误。

let person = {};
Object.defineProperty(person, "name", {
    configurable: false,
    value: "Nicholas"
});
console.log(person.name); // "Nicholas"
delete person.name;
console.log(person.name); // "Nicholas"

⚠️ 尝试删除[[Configurable]]false 的值在严格模式下会抛出错误

一旦某个属性被设定了 [[Configurable]] 值为false 以后, 该值将会被定义为不可配置, 也不能在变回可配置了。 也就是说,此时,如果再次调用Object.defineProperty() 并修改任何非 writable 属性还会导致错误。也无法被改变了。

⚠️此外,在调用Object.defineProperty() 时, 如果不指定configurable, enumerablewritable 值,则全部默认为 false

let obj = {  };
Object.defineProperty(obj, "name",{value:'jayce'});
let a = Object.getOwnPropertyDescriptors(obj)

console.log(a);//{ name: { value: 'jayce',writable: false,enumerable: false,configurable: false } }

注意: 如果已经有初始化值,则初始化时,数据属性已经被设定了默认值,都为true

// 注意: 如果已经有初始化值,则初始化时,数据属性已经被设定了默认值,都为true
let obj = { name:'frank' };
Object.defineProperty(obj, "name",{value:'jayce'});
let a = Object.getOwnPropertyDescriptors(obj)

console.log(a);// { name: { value: 'jayce',writable: true,enumerable: true,configurable: true } }

Object.defineProperties()

Object.defineProperties() 用于批量修改默认数据属性,其语法格式如下:

Object.defineProperties(obj,props)

示例:

var obj = {};
Object.defineProperties(obj, {
  'property1': {
    value: true,
    writable: true
  },
  'property2': {
    value: 'Hello',
    writable: false
  }
  // etc. etc.
});
1.1.1.2.2 访问数据属性

Object 提供了两个数据属性的访问方法,分别是:

  1. Object.getOwnPropertyDescriptor()
  2. Object.getOwnPropertyDescriptors()

Object.getOwnPropertyDescriptor() 用于获取单个对象值数据属性, 而Object.getOwnPropertyDescriptors() 则用于获取对象中所有值的数据属性。

示例:

let obj = { name:'frank',age:18,height:'175cm' };
Object.defineProperty(obj, "name",{value:'jayce'});
let res1 = Object.getOwnPropertyDescriptor(obj,'name')
let res2 = Object.getOwnPropertyDescriptors(obj)

console.log(res1);
/* 
{ value: 'jayce',
  writable: true,
  enumerable: true,
  configurable: true }
*/
console.log(res2);

/* { name: 
   { value: 'jayce',
     writable: true,
     enumerable: true,
     configurable: true },
  age: 
   { value: 18,
     writable: true,
     enumerable: true,
     configurable: true },
  height: 
   { value: '175cm',
     writable: true,
     enumerable: true,
     configurable: true } }
 */

1.1.2 访问器属性

访问器属性不包含数据值。

访问器属性有4个特性描述它们的行为:

  • [[Configurable]] : 表示属性是否可以通过 delete 删除并重新定义, 是否可以修改它的特性, 以及是否可以把它改为数据属性。 默认值为true
  • [[Enumerable]] : 表示属性是否可以通过 fot-in 循环返回。 默认值为 true
  • [[Get]] :获取函数, 在读取属性时调用。 默认值为 undefined
  • [[Set]] : 设置函数, 在写入属性时调用。默认值为 undefined

访问器属性是不能直接定义的, 必须使用Object.defineProperty()

// 定义一个对象, 包含伪私有成员 year_ 和公共成员 edition

let book = {
    year_: 2017,
    edition: 1
};

Object.defineProperty(book,"year",{
    get(){
        return this.year_;
    },
    set(newValue){
        if(newValue > 2017) {
            this.year_ = newValue;
            this.edition += newValue - 2017;
        }
    }
});

book.year = 2018;
console.log(book.edition); // 2

​ 这个例子中 对象 book 有两个默认属性 : year_editionyear_ 中的下划线常用来表示该属性并不希望在对象方法的外部被访问。 另一个属性 year 被定义为一个访问器属性, 其中获取函数简单地返回year_ 的值, 而设置函数会做一些计算以决定正确的版本(edition)。 因此,把year 属性修改为 2018 会导致 year_ 变成 2018, edition 变成2。 这是访问器属性的典型使用场景, 即设置一个属性值会导致一些其他变化发生

​ 获取函数 和 设置函数 不一定都要定义。只定义获取函数 —— 属性只读。只定义设置函数——不可读取

1.1.3 合并对象 —— Object.assign()

ES6 提供了 Object.assign() 方法用于对象合并, 这个方法接收一个目标对象,和一个或者多个源对象作为参数, 然后对每个源对象执行浅复制, 如果多个源对象有相同的属性, 则使用最后一个复制的值。用例:

let dest = { id: 'dest' };
let result = Object.assign(dest,{ id: 'src1', a:'foo'}, { id :'src2',b:'bar'});
console.log(result);//{id: 'src2', a: 'foo', b: 'bar'}

注意:实际的逻辑实现是,将每个源对象中可枚举(Object.propertyIsEnumerable() 返回 true) 和 自有(Object.hasOwnProperty() 返回 true ) 的属性复制到目标对象。 以字符串和符号为键的属性会被复制。 对每个符合条件的属性,这个方法会使用源对象上的 [[Get]] 取得属性的值,然后使用目标对象上的 [[Set]] 设置属性的值。

1.1.4 对象标识与相等判定 —— Object.is()

ES6 之前,=== 对有一些结果的判定在不同的js引擎中表现不一样, ES6 中, 规范新增了一个统一方法, 考虑了一些边界情形,输出正常判定:

如:

console.log(+0 === -0);// true
console.log(+0 === 0);// true
console.log(-0 === 0);// true
console.log(Object.is(+0,-0));// false
console.log(Object.is(+0,0));// true
console.log(Object.is(0,0));// false

1.1.5 增强的对象语法

  1. 属性值简写

    给对象添加变量是,属性名和以变量作为属性值的变量名如果是一样的,可以直接简写:

    let name = 'Matt';
    let person = {
        name: name
    }
    // 可以简写为:
    let name = 'Matt';
    let person = {
        name
    };
    
  2. 可计算属性

    ES6 之前,对象的key 只能是字符串形式,现在可以使用变量,动态的访问和设定

    const nameKey = 'name';
    const ageKey = 'age';
    const jobKey = 'job';
    let person = {
        [nameKey]:'Matt';
        [ageKey]:27;
    	[jobKey]:'Software Engineer'
    }
    

    标签:console,log,对象,理解,原型,构造函数,name
    From: https://www.cnblogs.com/jaycethanks/p/17365963.html

相关文章

  • OOP面向对象第二个月学习总结
    OOP面向对象第二个月学习总结目录 · 前言 · 设计与分析 · 踩坑心得 · 改进建议 · 总结 一、前言这个月的学习相比上个月的学习,难度就提升了极多,为了让我们更好的理解面向对象的几个特点和原则,题目以及作业的难度,复杂度,综合性增加了许多。主要有几次实验,......
  • 面向对象程序设计题目集总结blog2-22206110-胡瑞杰
    一、前言第二次在博客园上发布面向对象程序设计题目集的总结博客。经过几周的学习,面向对象的理念更加深入。虽然已经学了些面向对象程序设计,学好这部分内容还是有较大难度。关于知识点本次的题目集所体现的知识点已经不仅限于Java的语法知识,还需要考虑设计问题,不......
  • android之间传递多个对象  IPC也是…
    第一步:新建一个Android工程命名为ObjectTranDemo(类比较多哦!)目录结构如下图: 第二步:修改main.xml布局文件(这里我增加了两个按钮)代码如下<?xmlversion="1.0"encoding="utf-8"?>  <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"an......
  • JSP 的本质原理解析:"编写的时候是JSP,心里想解读的是 java 源码"
    JSP的本质原理解析:"编写的时候是JSP,心里想解读的是java源码"@目录JSP的本质原理解析:"编写的时候是JSP,心里想解读的是java源码"每博一文案1.JSP概述2.第一个JSP程序3.JSP的本质就是Servlet4.JSP的基础语法4.1在JSP文件中直接编写文字4.2在JSP中编写Java程序......
  • python 类与对象
    类和对象的基本概念类:类是一种模板或者蓝图,用于描述一类对象所具有的属性和方法。类定义了对象的基本结构,包括属性和方法。对象:对象是类的一个实例,是具体实现某个类的一个具体实体。每个对象都有自己的属性和方法。类和对象的应用在Python中,可以通过定义类来创建对象,并......
  • 创建队列时对结构体指针的理解
    1#include<stdio.h>2#include<stdlib.h>34#defineElemTypeint56//定义队列结点7typedefstructQNode8{9ElemTypedata;10structQNode*next;11}QNode,*QNodePrt;1213//定义队首、队尾指针14typedefstruct15{16QNo......
  • koa-cors 源码及基本原理解析
    cors: 跨域资源共享(Cross-OriginResourceSharing)是一种机制,用来允许不同源服务器上的指定资源可以被特定的Web应用访问。在koa项目中使用cors中间件:eg:1varkoa=require('koa');2varroute=require('koa-route');3varcors=require('koa-cors');4varapp......
  • lab5:深入理解进程切换
    目录linux操作系统分析Lab5:深入理解进程切换context_switch函数执行过程1.prepare_task_switch()2.arch_start_context_switch()3.switch_mm_irqs_off()进程地址切换3.switch_to()实验总结linux操作系统分析Lab5:深入理解进程切换context_switch函数content_switch函......
  • 关于完美转发中forward的作用的一点理解
     首先先描述一下C++中各种类型的值(以下无特殊说明“类型”皆按如下分法)lvalue(leftvalue)左值:有标识符,且不能被回收rvalue(rightvalue)右值:有无标识符皆可,可以被回收glvalue(generalizedleftvalue)泛左值:有标识符,可不可被回收皆可prvalue(purerightvalue)纯右值:没有标识符......
  • window10删除3D对象等7个文件夹
    注册表管理器regeditHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\按照需要,删除以下7个文件夹。[3D对象][视频][音乐][图片][下载][桌面][文档]......