原生JS基础知识
JS 对象的属性的特性
-
数据属性 ( 我们平常看到的对象普通属性 )
-
值 ( value )
-
可写性 ( writable )
-
可枚举性 ( enumerable )
-
可配置性 ( configurable )
- Tips : 所有属性权限在被设置为false的时候是该权限最后一次可被修改的时候 , 一旦置为false就无法置回true
-
-
存储器属性 ( 由getter和setter定义的属性 )
-
读取 ( get )
-
写入 ( set )
-
可枚举性 ( enumerable )
-
可配置性 ( configurable )
var aa = { x: 1, get y() { return 1000 }, set y(value) { this.x += value } } console.log(aa) aa.y = 1 console.log(aa)
-
属性的操作符
delete
-
断开属性和宿主对象的联系
// delete只能删除自有属性 , 不能删除继承属性 Object.prototype.hobby = 'swim' var son = {} console.log(son.hobby) console.log(delete son.hobby) console.log(son.hobby) // 属性一旦经历var操作则不可配置 , 无法delete不可配置的属性 var test = 123; console.log(Object.getOwnPropertyDescriptor(window, 'test')) // f12打印 : {value: 123, writable: true, enumerable: true, configurable: false}
in
-
检测对象自有属性和继承属性
var foo={ x: 1 } console.log('x' in foo) console.log('y' in foo) console.log('toString' in foo)
属性的方法
Object.getOwnPropertyDescriptor()
-
获取某个对象特定属性的属性描述 , 对于一个不存在的属性或者继承属性返回undefined
var foo = { name: 'liu', get age() { return 18 } } console.log(Object.getOwnPropertyDescriptor(foo, 'name')) console.log(Object.getOwnPropertyDescriptor(foo, 'age')) console.log(Object.getOwnPropertyDescriptor(foo, 'xxxx')) console.log(Object.getOwnPropertyDescriptor(foo, 'toString'))
Object.create() : 用指定对象作为原型创建对象
-
第一个参数是新建对象的原型
-
第二个参数是属性和特性描述的集合
var father = { lastName: 'liu' } var son = Object.create(father, { age: { value: 18, writable: false, enumerable: true, configurable: true, } }) console.log(son) console.log(Object.getOwnPropertyDescriptor(son, 'age')) console.log(son.lastName)
Object.defineProperty()
-
用于定义某个新建属性的特性
// 不能修改继承属性 Object.prototype.hobby = 'swim' var father = { lastName: 'liu' } Object.defineProperty(father, 'hobby', { value: 'ball', enumerable: true, }) console.log(father) console.log(father.__proto__) // 对于新创建的属性来说默认是false或者undefined Object.defineProperty(father, 'age', {}) console.log(Object.getOwnPropertyDescriptor(father, 'age')) // 尝试修改不可写的属性会失败但不报错 , 但在严格模式下会报错 Object.defineProperty(father, 'age', { value: 40, writable: false, enumerable: false, configurable: true }) father.age = 42 console.log(father.age) // 不可枚举数据属性age , 但是lastName可以枚举 for (let key in father) { console.log(key) } // 因为属性age是可配置的 , 故可通过配置的方式对值进行修改 Object.defineProperty(father, 'age', { value: 42, }) console.log(father.age) // 可将数据属性设置为存储器属性 Object.defineProperty(father, 'age', { get: function() { return 42 }, }) console.log(father.age)
Object.defineProperties()
-
同时定义多个新建属性的特性
var father = {} Object.defineProperties(father, { lastName: {value: 'liu',writable: false,enumerable: true,configurable: false}, age: {value: 40,writable: false,enumerable: true,configurable: false}, son: { get: function() { return 'xiaoliu' }, enumerable: false, configurable: false } }) for(let key in father){ console.log(key, '---', father[key]) } console.log('son', father.son)
Object.preventExtensions() && Object.isExtensible()
-
前者将对象设置为不可扩展 ( 不可添加新属性 )
-
后者检测对象是否可扩展
function Father() {} function Son() {} var father = new Father() Son.prototype = father var son = new Son() Object.preventExtensions(son) console.log(Object.isExtensible(son)) // Object.preventExtensions只会影响对象本身的可扩展性 , 所以依然可以给对象原型添加属性 son.lastName = 'li' console.log(son.lastName) son.__proto__.lastName = 'liu' console.log(son.lastName)
Object.seal() && Object.isSealed()
-
将对象封印 && 检测对象是否被封印
var foo = { y: 2 } console.log(Object.getOwnPropertyDescriptor(foo, 'y')) Object.seal(foo) console.log(Object.getOwnPropertyDescriptor(foo, 'y')) console.log(Object.isSealed(foo))
Object.freeze() && Object.isFrozen()
-
将对象冻结 && 检测对象是否被冻结
var foo = { x: 1 } console.log(Object.getOwnPropertyDescriptor(foo, 'x')) Object.freeze(foo) console.log(Object.getOwnPropertyDescriptor(foo, 'x')) console.log(Object.isFrozen(foo))
Object.keys() && Object.getOwnPropertyNames()
-
将对象中的属性名以数组的形式枚举出来
var foo = { x: 1, y: 2 } Object.defineProperty(foo, 'z', { value: 3, writable: true, enumerable: false, configurable: true, }) console.log(foo) console.log(Object.keys(foo)) console.log(Object.getOwnPropertyNames(foo))
hasOwnProperty()
-
只检测对对象自有属性 , 不检测继承属性
var aa={x:1} console.log(aa.hasOwnProperty('x')) console.log(aa.hasOwnProperty('y')) console.log(aa.hasOwnProperty('toString'))
propertyIsEnumerable()
-
只检测自有属性的可枚举属性
var aa = { x: 1 } Object.defineProperty(aa, 'y', { value: 1, writable: true, enumerable: false, configurable: true }) console.log(aa) console.log(aa.propertyIsEnumerable('x')) console.log(aa.propertyIsEnumerable('y')) console.log(aa.propertyIsEnumerable('toString'))