js面向对象编程,你需要知道这些
2021-11-07 本文已影响0人
一颗冰淇淋
javascript中对象由key和value组成,key是标识符,value可以为任意类型
创建对象的方式
1、通过构造函数
var obj = new Object()
obj.name = 'alice'
obj.age = 18
2、通过字面量
var obj = {
name: 'alice',
age: 18
}
属性描述符
对属性进行精准的操作,比如定义属性是否可被删除、遍历或修改
1、语法
//定义一个属性
Object.defineProperty(Object, PropertyKey, attributes)
// 定义多个属性
Object.defineProperties(Object, properties)
2、属性描述符特征
属性 | 描述 | 通过对象定义时默认值 | 通过属性描述符定义时默认值 |
---|---|---|---|
configurable | 定义属性是否可被删除、重新定义 | true | false |
enumerable | 定义属性是否可被枚举,如通过for in/Object.keys | true | false |
writable | 是否可被修改 | true | false |
value | 读取属性和修改的时候操作的值 | undefined | undefined |
get | 获取属性时会执行的函数 | undefined | undefined |
set | 设置属性时会执行的函数 | undefined | undefined |
3、属性描述符的分类
属性描述符分为数据属性描述符和读取属性描述符,数据属性描述符用来定义属性,读取属性描述符用于为函数中不愿意暴露的属性来进行读取和设置的操作
不同属性描述符可操作的属性也不一样
分类 | configurable | enumerable | writable | value | get | set |
---|---|---|---|---|---|---|
数据属性描述符 | √ | √ | √ | √ | × | × |
存取属性描述符 | √ | √ | × | × | √ | √ |
4、定义
给obj对象添加skill属性,属性的描述为不可删除或重新定义、不可修改、可枚举
var obj = {
name: 'alice',
age: 18
}
Object.defineProperty(obj, 'skill', {
configurable: false,
writable: false,
enumerable: true,
value: 'flying',
})
console.log(obj)
delete obj.skill
console.log(obj)
obj.skill = 'swimming'
console.log(obj)
所以上面删除和修改都是无效的操作,执行结果如下
属性描述符.png对象的其它方法
1、获取对象的属性描述符
- getOwnPropertyDescriptor
- getOwnPropertyDescriptors
2、操作属性
- preventExtensions 禁止新增属性
- seal 封闭属性,即禁止新增、删除属性
- freeze 冻结属性,即禁止新增、修改、删除属性
3、查询属性
- isExtensible 查询是否可新增属性
- isSealed 查询是否是封闭的属性
- isFrozen 查询是否是冻结的属性
var user = {
name: 'kiki',
age: 18
}
console.log('getOwnPropertyDescriptor', Object.getOwnPropertyDescriptor(user, 'name'))
console.log('getOwnPropertyDescriptors', Object.getOwnPropertyDescriptors(user))
Object.preventExtensions(user)
console.log('isExtensible', Object.isExtensible(user))
user.skill = 'flying'
console.log('user', user)
Object.seal(user)
console.log('isSealed', Object.isSealed(user))
delete user.age
console.log('user', user)
Object.freeze(user)
console.log('isFrozen', Object.isFrozen(user))
user.name = 'alice'
console.log(user)
以上代码执行结果如下
对象的其它方法.png原型
1、隐式原型
每一个对象都有隐式原型,可通过Object.getPrototypeOf或者proto(存在浏览器兼容问题)获取,查找元素时,如果自身对象没有,会向原型上查找
var obj = {}
console.log(obj.__proto__)
console.log(Object.getPrototypeOf(obj))
console.log(obj.name)
obj.__proto__.name = 'alice'
console.log(obj.name)
对象的隐式原型指向空对象
隐式原型.png2、显式原型
每个函数除了有隐式原型,还有显式原型prototype,prototype中有一个属性constructor指向函数自己
function foo(){}
console.log(foo.__proto__)
console.log(foo.prototype)
console.log(Object.getOwnPropertyDescriptors(foo.prototype))
显式原型.png
构造函数
在构造函数中,通过new关键字可以批量创建对象
1、定义方式
function foo()
var f = new foo()
2、new关键字的操作
- 在内存中创建一个新对象(空对象)
- 对象的proto属性被赋值为构造函数的prototype属性
- 构造函数的this,将指向创建的对象
- 执行构造函数的代码
- 如果函数没有返回非空对象,则返回创建的新对象
3、在内存中的表现
new关键字会将创建的对象的proto属性赋值为构造函数的prototype属性
function Person(){}
var p1 = new Person()
var p2 = new Person()
console.log(p1.__proto__ === Person.prototype) // true
console.log(p1.__proto__ === p2.__proto__) // true
图示如下
函数显式原型与对象隐式原型的关系.png以上就是面向对象编程的部分内容,下一篇记录js中实现继承的方式,关于js高级,还有很多需要开发者掌握的地方,可以看看我写的其他博文,持续更新中~