@jsongao98
2021-04-24T12:12:17.000000Z
字数 6320
阅读 83
JavaScript
new
return
对象的属性必须是字符串(强制toString)形式
使用"."来访问属性时,静态的,右侧必须是一个以属性名称命名的简单标识符。属性名用一个标识符来表示。标识符必须直接出现再js程序中,它们不是数据类型,因此程序无法修改它们。
使用"[]"访问属性,动态的,方括号里必须是一个计算结果为字符串的表达式,属性名通过字符串表示。字符串是js的数据类型,在程序运行时可以修改和创建它们。
分类:数据属性和访问器属性(当个一个属性定义getter、setter或者两者都有时,这个属性就成了访问器属性)
数据属性的特性
[[Configurable]]
[[Enumerable]]
[[Writable]]
[[Value]]
访问器属性的特性
[[Configurable]]
[[Enumerable]]
[[Get]]:get ...(){}
[[Set]] :set...(){}
定义属性特性
Object.defineProperties( obj,{ property1:{特性} ,property2:{特性}, ..... } )
Object.defineProperty( obj,property,{ 特性 } )
读取属性特性
Object.getOwnPropertyDescriptors(obj)// 返回一个对象,包含所有实例属性 键名:{特性}
Object.getOwnPropertyDescriptor(obj,property)
遍历属性的方法(5)
for...in
循环遍历对象自身和继承的可枚举属性(不包含Symbol)${key}:${obj[key]}
。
MDN: 可枚举属性是指那些内部 “可枚举”(propertyIsEnumberable) 标志设置为 true 的属性,对于通过直接的赋值和属性初始化的属性,该标识值默认为即为 true,对于通过 Object.defineProperty 等定义的属性,该标识值默认为 false。可枚举的属性可以通过 for...in 循环进行遍历(除非该属性名是一个 Symbol)。
for-of
MDN:for...of语句在可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环,遍历的是可迭代属性,调用自定义迭代钩子,并为每个不同属性的值执行语句.
Object.keys(obj)
返回一个数组,同for...in但不包含继承的属性
Object.getOwnPropertyNames(obj)
返回一个数组,包含对象自身 所有( 不包含Symbol但包含不可枚举属性 )属性的键名
Object.getOwnPropertySymbols(obj)
返回一个数组,包含对象自身所有Symbol属性的键名
Reflect.ownKeys(obj)
返回一个数组,包含对象自身的(不包含继承)的所有(Symbol、字符串)属性(可枚举不可枚举)的键名
关于遍历还有数组的map( ), filter( ), forEach( ).....
map和forEach的区别:map返回一个新的数组,forEach在原数组基础上修改
Object.assign(目标obj,源obj)
修改并返回目标对象但属性的特性不被转移(getter、setter)
注意:是浅拷贝可枚举的实例属性
Object.keys()
:如果是数组则返回其索引
Object.values()
Object.entries()
:返回键值对数组
Object.fromEntries()
:由(可迭代)数组创建对象
Object.is(obj,obj)
Object.[prototype].hasOwnProperty()
Object.setPrototypeOf(obj,obj)
Object.getPrototypeOf()
Object.creat(prototype,[[descriptors]])
创建一个空对象并指定其原型,可选项:修对象的属性特性
三种克隆对象的方法,并拷贝对象原型:(都是浅拷贝,但三种有区别)
普通拷贝(只拷贝实例属性):Object.assign({},obj)
let clone1={ _proto_:Object.getPrototypeOf( obj ), ...obj}
proto在非浏览器的环境不一定部署,推荐写法2、3
let clone2=Object.assign( Object.creat( Object.getOwnPrototypeOf(obj) ),obj )
let clone3=Object.creat( Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj) )
这种最为彻底,实例属性的特性也拷贝
instanceof
isPrototypeOf
obj?.property
obj?.[property] 同上
function?.()
?. 左边部分的值可以为null或undefined,若是,即为短路机制,表达式返回undefined。
?. 不能在赋值语句左侧,只能用来读取和删除 ,不能写入 (delete user?.name;// 如果 user 存在,则删除 user.name)
老的办法
解构赋值语法是一种 Javascript 表达式。通过解构赋值, 可以将属性/值从对象/数组中取出,赋值给其他变量。
等号右边必须是对象
或通过包装类型对象强制转换为对象、null/undefined无法转对象则报错,空对象则为undefined;其中,String包装类型对象会这样:{...'hello'} -> {0: "h", 1: "e", 2: "l", 3: "l", 4: "o"})
。左边定义了要从原变量提取什么变量(即变量名等号左右对应)。
浅拷贝对象可枚举的属性键值对,解构数组index作为键名。
扩展运算符... 的解构赋值只能 是对象自身的属性,即不包含继承(原型)上的属性
运用...的解构赋值 ...后只能是变量名不能是表达式如{.....}(因为要解构赋值,要调用get、set,表达式没有get方法)
使用...的解构赋值必须是最后一个参数
...可用来收集函数参数,只能在末尾
...用来生成array/object副本(浅拷贝)
{ ...obj }
[ ...obj ] 和 Array.from(obj)
的区别 (用来遍历生成数组)
Array.from()
适用于可迭代对象和类数组对象。等同于
let objCopy=Object.assign({},obj);
let arrCopy=Object.assign([],arr);
use strict /类方法enumerable:false/类表达式(仅内部可见)、类声明的区别
extends后可以接任意表达式来生成父类
Rabbit extends Animal 创建了两个 [[Prototype]] 引用:
Rabbit 函数原型继承自 Animal 函数
Rabbit._proto_== Animal
继承静态方法属性
Rabbit.prototype 原型继承自 Animal.prototype
Rabbit.prototype._proto_== Animal.prototype
构造函数的[[prototeype]]最终指向Function.prototype;原型的[[prototype]]最终指向Object.prototype
重写方法:super.method(...)
来调用一个父类方法
重写constructor
同其他构造函数一样,new一个基类(typeof...== function,其实也是函数)的时候,基类constructor(...)会创建一个空对象并赋值给this;派生类constructor(...)并不会执行此操作,所以派生类constructor中必须先super(...)调用父类的constructor 再使用this。
重写类字段的问题(使用方法或通过getter、setter替代类字段解决)
类字段初始化顺序
对于基类(还未继承任何东西的那种),在构造函数调用前初始化。
对于派生类,在 super(...) 后立刻初始化。
new this(...)
非程序上强制但是约定的:以“_”,通过get/set、getter/setter语法来约束属性的读取写入,叫做受保护的字段,是可以被继承的
真正意义上的私有属性:“#”开头
私有字段和公有字段不冲突,可以通过设置公有字段的getter、setter来间接访问私有字段
私有字段不能通过this[#...]访问
polyfill
Funtion.prototype === Function._proto_ === Object._proto_ === Array._proto_
Object.prototype === Array.prototype._proto_ === Function.prototype._proto_ === ....prototype._proto_
链式调用:每一次 map.set 调用都会返回 map 本身,所以我们可以进行“链式”调用:
map.set('1', 'str1')
.set(1, 'num1')
.set(true, 'bool1');
let map = new Map(Object.entries(obj))
由 普通对象 创建 一个 map数据类型let obj = Object.fromEntries(map.entries())
由 map 创建 一个 普通对象注意:
map[key] 不是使用 Map 的正确方式,虽然 map[key] 也有效,例如我们可以设置 map[key] = 2,这样会将 map 视为 JavaScript 的 plain object,因此它暗含了所有相应的限制(没有对象键等)。
所以我们应该使用 map 方法:set 和 get 等。