【JS】对象部分知识

javaScript对象

对象

对象用来存储键值对和更复杂的实体。

  • 创建
let user=new Object();//构造函数的语法
let user={};//字面量的语法
  • 用点号或方括号访问属性值,方括号比点符号更强大。它允许任何属性名和变量,但写起来也更加麻烦
  • delete 操作符移除属性
  • 用多字词语作为属性名,必须加上引号
  • 属性名会被自动转换成字符串

列表中的最后一个属性以都好结尾,叫做尾随或悬挂逗号,便于添加、删除和移动属性。

  • 使用ocnst声明的对象可以被修改其中的内容,而不能指向另一个对象。

  • 计算属性

let bag={
	[fruit]:5,//其中fruit为变量名
}
  • 属性值简写,也可以和正常方式混用。
function makeUser(name, age) {
  return {
    name, // 与 name: name 相同
    age,  // 与 age: age 相同
    // ...
  };
}
  • 属性存在性测试:In操作符

javaScript可以访问任何属性,若属性不存在则会得到undefined,检查属性是否存在用In

通常情况下不要给属性赋值为undefined,赋值为null;

  • for…in循环
for(let key in user)
{
...
}

属性键的顺序:若为整数类型则按从大到小排序,若不是整数类型则按照定义的先后顺序排序。

对象引用和复制

与原始类型相比,对象的根本区别之一是对象是“通过引用”被存储和复制的,与原始类型值相反:字符串,数字,布尔值等 —— 始终是以“整体值”的形式被复制的。

复制对象时复制了其引用(内存地址),通过复制后的引用进行对象的修改会影响对象本身。

  • 引用的比较:只有引用指向的两个对象为同一对象时,两者才相等。两个独立但内容相等的对象并不相等。

  • 克隆与合并:若真想完全复制一个对象,则需要创建一个新的对象,并通过遍历现有属性的结构,复制到新对象中。或者可以采用object.assgin

Object.assign(dest,[src1,src2,src3,...])

可以用它来合并多个对象

let user = { name: "John" };

let permissions1 = { canView: true };
let permissions2 = { canEdit: true };

// 将 permissions1 和 permissions2 中的所有属性都拷贝到 user 中
Object.assign(user, permissions1, permissions2);

// 现在 user = { name: "John", canView: true, canEdit: true }
//或者:
let clone = Object.assign({},user)
  • 深层克隆

当属性为其他对象的引用时,拷贝后的属性会与原属性共用同一对象。

为了解决此问题,我们应该使用会检查每个 user[key] 的值的克隆循环,如果值是一个对象,那么也要复制它的结构。这就叫“深拷贝”。

工具:使用现成的实现,例如 JavaScript 库 lodash 中的 _.cloneDeep(obj)

垃圾回收

javascript的内存管理是自动的;

可达性

内部算法

  • 垃圾收集器找到所有的根,并“标记”(记住)它们。
  • 然后它遍历并“标记”来自它们的所有引用。
  • 然后它遍历标记的对象并标记 它们的 引用。所有被遍历到的对象都会被记住,以免将来再次遍历到同一个对象。
  • ……如此操作,直到所有可达的(从根部)引用都被访问到。
  • 没有被标记的对象都会被删除。

对象方法

在对象中属性的值可以是一个函数,函数就是该对象的action,该函数称为对象方法。

let user = {
  name: "John",
  age: 30
};
user.sayHi=function(){
	alert("Hello!");
};
user.sayHi();//Hello!
  • 方法简写
let user={
	sayHi(){
		alert("Hello");
	}
};
//和上面的完全等价,可以省略function,只写sayHi().
let user={
	sayHi: function(){
		alert("Hello!");
	}
};

用this访问对象内部的信息。

this的值是在代码运行时计算出来的,取决于代码上下文。

在没有对象的情况下调用this==undefined,this将会是全局对象。

  • 注意:箭头函数没有自己的this

构造器和操作符new

构造函数

命名以大写字母开头,只能由new操作符来执行。

从技术上讲,任何函数都可以用作构造器。即:任何函数都可以通过 new 来运行,它会执行上面的算法。“首字母大写”是一个共同的约定,以明确表示一个函数将被使用 new 来运行。

构造器不能被再次调用,因为它不保存在任何地方,只是被创建和调用。因此,这个技巧旨在封装构建单个对象的代码,而无需将来重用。

构造器通常没有return语句

如果没有参数,可以省略new后的括号。

可选链?.

不存在的属性的问题

要验证属性是否存在,用&&和?:都比较麻烦,需要重复写对象属性名。

如果可选链 ?. 前面的部分undefined 或者 null,它会停止运算并返回该部分,也就是undefined。

let user={};

alert(user?.address?.street);//undefined,不会报错
//即使对象user不存在,上述读取地址操作也没关系

不要过度使用可选链

我们应该只将 ?. 使用在一些东西可以不存在的地方。

例如,如果根据我们的代码逻辑,user 对象必须存在,但 address 是可选的,那么我们应该这样写 user.address?.street,而不是这样 user?.address?.street

所以,如果 user 恰巧因为失误变为 undefined,我们会看到一个编程错误并修复它。否则,代码中的错误在不恰当的地方被消除了,这会导致调试更加困难。

  • 短路效应

若?.左部不存在,就会立即停止运算,后面又任何函数调用或者副作用都不会执行。

  • 其他变体:?.() ?.[]

用?.()调用一个可能不存在的函数,用?.[]从一个可能不存在的对象上安全地读取属性。

?.可以和delete一起使用,但不能用作左值。

  • 总结
  1. obj?.prop —— 如果 obj 存在则返回 obj.prop,否则返回 undefined
  2. obj?.[prop] —— 如果 obj 存在则返回 obj[prop],否则返回 undefined
  3. obj.method?.() —— 如果 obj.method 存在则调用 obj.method(),否则返回 undefined

Symbol类型

对象的属性键只能是字符串类型或者Symbol类型。

Symbol是唯一标识符的基本类型。

Symbol值表示唯一的标识符,创建时可以给Symbol一个描述,也成为Symbol名,在代码调试时有用。

let id=Symbol("id");

Symbol不会被自动转换为字符串。调用.toString()可以显示转换;或者获取symbol.description;

  • 隐藏属性

应用:为第三方代码添加标识符;

对象字面量中的symbol:使用方括号将其括起来,因为我们需要Id的值作为键,而不是字符串id。

  • symbol在for…in中会被跳过,但Object.assign会同时复制字符串和symbol属性。
  • 全局symbol

全局symbol注册表:保证每次访问相同名字的symbol返回相同的symbol值。

在注册表中读取(不存在则创建)Symbol,使用Symbol.for(key)。该调用会检查全局注册表,如果有一个描述为 key 的 Symbol,则返回该 Symbol,否则将创建一个新 Symbol(Symbol(key)),并通过给定的 key 将其存储在注册表中。

  • 反向调用:symbol.keyFor(sym),通过全局Symbol返回一个名字。

内部使用全局Symbol注册表来查找Symbol的键,所以其不适用于非全局Symbol.

具体查看https://zh.javascript.info/symbol教程。

对象-原始值转换

对象被运算时会自动转换为原始值。

对象到原始值的转换,是由许多期望以原始值作为值的内建函数和运算符自动调用的。

这里有三种类型(hint):

  • "string"(对于 alert 和其他需要字符串的操作)
  • "number"(对于数学运算)
  • "default"(少数运算符)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值