nanoid(现在这放着,懒得开新的了)
安装 yarn add nanoid
使用 import {nanoid} from ‘nanoid’;
语法 nanoid()即可生成随机字符
instanceof
检查实例的原型链中,是否包含指定构造函数的原型
function Person(name) { this.name = name } const p1 = new Person('小红'); console.log(p1 instanceof Person) //true console.log(p1 instanceof Object) //true console.log(Person.prototype instanceof Object) //true
isPrototypeOf()
本质上,会在传入参数的[[prototype]]指向调用它的对象时返回true
function Person(name) { this.name = name } const p1 = new Person('小红'); const p2 = new Person('小明'); console.log(Person.prototype.isPrototypeOf(p1)) //true console.log(Person.prototype.isPrototypeOf(p2)) //true
Object.getPrototypeOf(obj)
可以方便的取得一个对象的原型。
function Person(name) { this.name = name } const p1 = new Person('小红'); console.log(Object.getPrototypeOf(p1)) //{constructor:f} console.log(Object.getPrototypeOf(p1)==Person.prototype) //true
Object.setPrototypeOf()
可以向实例的私有属性[[prototype]]写入一个新值,这样就可以重写一个对象的原型继承关系
【注意】这个方法可能会影响代码性能,会涉及所有访问了拿些修改过[[prototype]]的对象的代码
Object.setPrototypeOf(p1, p2)// p1.__proto__===p2
Object.create()
来创建一个新对象,同时为其指定原型
let biped = { numLegs: 2 }; let person = Object.create(biped) person.name = 'Matt'; console.log(person.name); //'Matt' console.log(person.numLegs); //2 console.log(Object.getPrototypeOf(person) === biped); //true
原型层级
在通过对象访问属性时,会按照这个属性的名称开始搜索,搜索开始对象实例本身。
如果在这个实例上发现了给定的名称,则返回该对象名称对应的值
如果没有找到属性,则搜索会沿着指针进入原型对象,找到则返回该属性对应的值,
这也就是原型用于在多个对象实例间共享属性的原理。
【注意】通过实例读取原型对象的值是不可更改的,如果在实例上添加一个与
原型对象同名的属性,则会在实例上创建这个属性,这样会遮住原型对象的属性
delect操作符
可以完全删除实例上的属性
function Person(name) { this.name = name; } let p1 = new Person('小红'); Person.prototype.name = '小明'; console.log(p1.name) //'小红' delete p1.name; console.log(p1.name) //'小明'
hasOwnProperty()
检测是否为实例属性
function Person() { } let p1 = new Person(); let p2 = new Person(); Person.prototype.name = '小明'; p1.name = '小红'; console.log(p1.hasOwnProperty('name')) //true console.log(p2.hasOwnProperty('name')) //false
Object.getOwnPropertyDescriptor()
取得原型属性的描述符(只对实例属性有效)
function Person() { } let p1 = new Person(); let p2 = new Person(); Person.prototype.name = '小明'; p1.name = '小红'; console.log(Object.getOwnPropertyDescriptor(p1, 'name')) //{value: "小红", writable: true, enumerable: true, configurable: true} console.log(Object.getOwnPropertyDescriptor(p2, 'name')) //undefined
in操作符
function Person(name) { } let p1 = new Person(); console.log('name' in p1) //false p1.name = '小明' console.log('name' in p1) //true let p2 = new Person(); console.log('name' in p2) //false Person.prototype.name = '小红' console.log('name' in p2) //true //结论,无论属性在实例自身还是原型上都会返回true
利用in和hasOwnProperty的特性实现检测属性是否存在于原型上
function detectionP(obj, k) { return !obj.hasOwnProperty(k) && ([k] in obj) } console.log(detectionP(p2, 'name'))
for-in循环中使用in操作符时,可以通过对象访问且可以被枚举的属性都会返回,
包括实例属性和原型属性
function Person(name) { this.name = name } Person.prototype.age = 10 let p1 = new Person('小红'); Object.defineProperties(p1, { "school": { value: 'bgs', enumerable: true //默认false }, "class": { value: '1908' } }) console.log(p1) //Person {name: "小红", school: "bgs", class: "1908"} for (let k in p1) { console.log(k) // name,school,age }
Object.keys()
接收一个对象作为参数,返回包含该对象所有可枚举属性名称的字符串数组
function Person(name) { this.name = name } let p1 = new Person('小红'); Object.defineProperties(p1, { "school": { value: 'bgs', enumerable: true //默认false }, "class": { value: '1908' } }) console.log(Object.keys(p1)) //['name']
Object.getOwnPropertyNames()
只要是实例属性(包含原型),无论是否可以枚举,返回对象所有属性名称的字符串数组
function Person(name) { this.name = name } let k1 = Symbol('k1') let p1 = new Person('小红'); Object.defineProperties(p1, { "school": { value: 'bgs', enumerable: true //默认false }, "class": { value: '1908' }, [k1]: { value: 1 } }) console.log(Object.getOwnPropertyNames(p1)) //["name", "school", "class"]
Object.getOwnPropertySymbols()
只针对符号,类似getOwnPropertyNames
语法Object.getOwnPropertySymbols(obj)
属性枚举的顺序
for-in和Object.keys()的枚举顺序是不确定的,取决于javascript引擎,
可能因浏览器而异
Object.getOwnPropertyName()、Object.getOwnPropertySymbols()
和object.assign()的枚举顺序是确定性的。
先以升序枚举数值键,然后以插入顺序枚举字符串和符号键,
在对象字面量中定义的键以它们逗号分隔的顺序插入。