js面向对象编程

从面向过程开发到面向对象开发,是个思维的重大转变,当真正理解了面向对象编程后,对于日常的开发就会有一个质的飞跃。

一. 面向过程与面向对象的区别

1.概念

1.面向过程
是一种以过程为中心的编程思想,面对问题,罗列出解决问题的步骤,然后按步骤一步步去实现
比如:蛋炒饭的制作,蛋和饭都混在一起,省事省力就能做出一盘美味可口的炒饭

2.面向对象
是以对象为核心,不需要关心程序内部的实现。解决问题时候,把问题抽象成对象,分析解决问题需要哪些对象,然后给对象里赋值一些方法和属性,让对象执行自己的方法,解决问题。
比如:盖浇饭的制作,把一份完整的饭拆分成米饭和菜,通过组合不同的米粉和菜能满足不同客户定制化的需求

2.区别

1.面向过程:
优点:性能较高
缺点:耦合性强,不易维护,扩展和复用

2.面向对象
优点:程序间低耦合,易于维护,扩展和复用,灵活配置
缺点:性能低于对象过程,因为面对对象需要实力化,比较消耗性能

二. 面向对象的特性

1.三大原则:封装,继承,多态

1.封装

1.概念:也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
封装可以给用户提供一个函数,函数里的方法属性不对外暴漏,而能实现用户想要实现的功能
好处:将变化隔离,程序便于使用,易于复用,安全性较高,
原则:隐藏不需要对外暴漏的属性,仅提供公共访问方式

2.继承

1.概念:让一个类拥有另一个类的属性和方法
2.创建对象的方式
1.对象字面量
const obj = {}
2.构造函数
const = new Object()
3.Object.create()

用这种方式创建一个空对象 Object.create(Object.prototype),类似 {},注意,Object.create(null)可以创建对象,但是这个对象没有原型,不会继承任何东西,连toString()方法都没有哦。

const obj1 = {name:'111'}
const obj2 = Object.create(obj1) 
console.log(obj2.name) // 111

2.继承的方式
1.原型链

1.1 基本思想:利用原型,让一个引用类型继承另一个引用类型的属性和方法

// 父函数
function Parent(){
  this.value1 = true
}
Parent.prototype.getParentValue = function(){
 return this.value1
}

// 子类函数
function Child(){
  this.value2 = false
}
// 这句话是最关键的。child 继承了parent的原型
Child.prototype = new Parent()

Child.prototype.getChildvalue = function(){
 return this.value2
}
const cc = new Child()
console.log(cc.getParentValue()) // true 这个是继承的父类的方法
console.log(cc.getChildvalue()) // false 自己的方法

1.2 缺点:
缺点1.实例共享引用类型,
原型链继承主要的问题是包含引用类型值的原型, 因为包含引用类型值的原型属性会被所有的实例共享, 而在通过原型来实现继承的时候, 原型实际变成了另外一个函数的实例(这里边就有可能存在引用类型)

缺点2.在创建 Child 的子类的时候,无法像继承元素传递参数

所以综上,这种继承方式少用

2.构造函数
3.组合继承
4.原型式继承
5.寄生式模式
6.寄生组合试继承

3.多态

三. 对象的特性

1.对象的方法

1.1 属性的简洁方

const name='zy'
const obj = {name:name}
// 简写
const obj1 ={name} 
console.log('obj1',obj1) // obj1: {name:'zy'}

1.2 属性名表达式

const obj = {name:'zy'}
obj.name // 'zy'
obj['name'] // zy

1.3 属性的可枚举和遍历 ***

1.可枚举性
1. Object.getOwnPropertyDescriptor

每个属性都有一个Descriptor,方法是 Object.getOwnPropertyDescriptor(对象,属性名)

const obj = {name:'zy'}
console.log(Object.getOwnPropertyDescriptor(obj,'name'))
//  {
//    configurable: true, // 是否可以删除
//    enumerable: true, // 是否可以枚举
//    value: zy,
//    writable: true, // 是否可以编辑
//  }
getOwnPropertydescriptor
2.Object.getOwnPropertyDescriptors

若要看整个对象的描述,可以用Object.getOwnPropertyDescriptors(obj)

const obj = {name:'zy',age:'1'}
Object.getOwnPropertyDescriptors(obj)
// {
// age: {
//  configurable: true,
//  enumerable: true,
//  value: "1",
//  writable: true,
//}
//name: {
//  configurable: true,
//  enumerable: true,
//  value: "zy",
//  writable: true,
//}
//}
Object.getOwnPropertyDescriptors
3.Object.defineProperty

这里可以看到通过对象字面量直接创建的属性默认是可以遍历,可以更改和可以删除的,下面我们通过另一种方法创建对象的属性,Object.defineProperty

const obj = {}
Object.defineProperty(obj,'name',{
  value:'zy'
})
console.log(obj) // {name:'zy}
console.log(Object.getOwnPropertyDescriptor(obj,'name'))
// {
// configurable: false
// enumerable: false
// value: 12
// writable: false,
// }
Object.defineProtery

通过对比可以发现,直接字面量创建的对象属性默认都是可以编辑遍历和删除的,而通过Object.definePorperty创建的对象属性则默认是不可编辑遍历和删除的。

扩展下 defineProperty的相关知识
configurable 是配置属性是否可以删除,默认true
enumerable 是配置属性是否可以枚举,默认true
writable 是配置属性是否可以编辑,默认true

4.Object.preventExtensions

Object.preventExtensions()方法让一个对象变的不可扩展,也就是永远不能再添加新的属性。
1.通过对象字面量新增属性,静默的失败

const obj = {name:'zy'}
Object.preventExtensions(obj)
obj.age = '1' //通过对象这种方式添加属性已经添加不上去了
console.log(obj) // {name:'zy'}

2.通过defineProperty给对象添加属性则直接报错

const obj = {name:'zy'}
Object.preventExtensions(obj)
Object.defineProperty(obj,'age',{value:'1'})
console.log(obj) 
// Uncaught TypeError: Cannot define property age, object is not extensible
5.Object.isExtensible()

Object.isExtensible() 方法判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)。

const obj = {name:'zy'}
Object.isExtensible(obj) // true
Object.preventExtensions(obj)
Object.isExtensible(obj) //false
6.Object.seal()

Object.seal()方法封闭一个对象,阻止添加新属性并将所有现有属性标记为不可配置。当前属性的值只要原来是可写的就可以改变。

7.Object.freeze()

方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze() 返回和传入的参数相同的对象。

2.遍历

对象的遍历总共有5种方式

1.for...in

for in可以遍历对象自身和继承的属性,不含不可枚举和Symbol

补充个知识点:in 操作符 和 hasOwnProperty
in和hasOwnProperty的区别
in 可以检查出自身和原型上的所有属性
hasOwnProperty 判断的自身的属性
通过这两个属性可以区分是哪些属性是自身的,哪些属性是原型上的

const obj = {
 name:'zy',
 age:'1',
}
// in 操作符
console.log('name' in obj) // true 自身的属性
console.log('age' in obj) // true 自身的属性
console.log('wdith' in obj) // false 不存在这个属性
console.log('toString' in obj) // true 原型上的方法

// hasOwnProperty
console.log(Object.hasOwnProperty('name')) // true 自身的属性
console.log(Object.hasOwnProperty('toString')) // false 不是自身的属性和方法

// 通过in 和 hasOwnProperty组合区分出原型的方法属性
in 返回true hasOwnProperty 返回false的就是原型上的方法
function isPropertyItem(item,obj){
  return item in obj  && !Object.hasOwnProperty(item)  
}
2.Object.keys(obj)

Object.keys,返回一个数组,可遍历对象自身属性,不含不可枚举和Symbol

3.Object.getOwnpropertyNames(obj)

getOwnpropertyNames ,返回数组,获取自身所有属性,包含不可枚举,不含Symbol

4.Object.getOwnPropertySymbols(obj)

Object.getOwnPropertySymbols 返回数组,获取自身所有Symbol属性

5.Reflect.ownKeys(obj)

Reflect.ownKeys返回一个数组,获取自身所有属性,包含 不可枚举和Symbol

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容