海阔凭鱼跃,天高任鸟飞。Hey 你好!我是猫力 Molly
一万个人心中有一万个哈姆雷特,一万个开发者心中便有一万种对面向对象思维的了解。这里我只浅显的论述一下我对面向对象思维的了解,不喜轻喷,欢送大家评论区留言探讨。
基本概念
在程序里,咱们通过应用对象去构建事实世界的模型,把本来很难(或不可)能被应用的性能,简单化并提供进去,以供拜访
这段解释摘抄自 MDN,读起来甚是绕口。
这里咱们能够采纳 填鸭法 来了解面向对象,大抵是说看起来像只鸭子,那么它就是一只鸭子。人与机器不同的是,人类具备主观意识而机器没有,一个具备尖尖的嘴,扁扁的脑袋,嘎嘎嘎的叫声并且还会游泳的生物,那么这便是咱们应用对象思维去构建了一只鸭子的类。机器不会像人一样主观意识去构想这其实是一只大鹅。
对象的组成
一个根本的对象由若干个数据类型组成,往大的类别上划分的话,能够分为 行为 和属性
属性:所有的数据类型都能够认为是对象的属性(小鸭子的体重,翅膀,脚丫子等等都是属性)
行为:个别指函数,赋予对象能力(小鸭子会游泳,那么游泳这个行为就是小鸭子的能力)
实例化对象
至此,咱们曾经创立了一只 鸭子类 ,这时候鸭子仅仅是一个初始化状态,相当于被冰封。咱们须要将鸭子解封,可应用new
关键字实例化鸭子对象。这样咱们便失去一个全新的鸭子对象。
new
关键字具体干了啥?可参考如下代码:
var obj = {};
// 获得该办法的第一个参数(并删除第一个参数),该参数是构造函数
var Constructor = [].shift.apply(arguments);
// 将新对象的外部属性__proto__指向构造函数的原型,这样新对象就能够拜访原型中的属性和办法
obj.__proto__ = Constructor.prototype;
// 获得构造函数的返回值
var ret = Constructor.apply(obj, arguments);
// 如果返回值是一个对象就返回该对象,否则返回构造函数的一个实例对象
return typeof ret === "object" ? ret : obj;
对象中的 this
对于 this
问题,很多初学者被这个 this
指向搞得昏头昏脑。其实搞懂 this
咱们只须要记住一句话 谁在调用它,它就指向谁,this 指向以后调用它的执行环境
经典例子:
var obj = {foo: function () {console.log(this.bar) },
bar: 1
};
var foo = obj.foo;
var bar = 2;
obj.foo() // 1
foo() // 2
js 中的数据类型分为根本数据类型和援用数据类型。根本数据类型是按值拜访,援用数据类型是按援用拜访。对象将所有的援用放入 栈将所有的值放入 堆,要获取一个对象值,须要先获取对象援用,而后依据援用找到对应的值。如果援用对应的值是一个函数,因为函数是一个独自的值,能够存在不同的执行上下文环境。那么问题来了,同样的函数在不同的环境下调用,咱们如何在函数外部获取以后执行环境呢?没错,this
的呈现正是为了解决此类场景问题。
总结:一堆属性和行为聚合到一起便形成了一个最根本的对象。可通过 new 关键字来实例化一个对象,因为执行环境的不同,对象外部的 this 指向也不同。在调用对象办法时,须要留神一下 this 的指向问题。
对象零碎
下面咱们提到了,一个根底对象的形成。然而在咱们理论开发当中远远比这简单的多,往往是多层对象的嵌套或者多个对象通过某个映射文件互相关联又或者一个对象继承自另一个对象 … 从而去构建一个更宏大的对象世界,解决更简单的利用场景,咱们把这种简单对象称之为 对象零碎 ,把这种思维称之为 面向对象编程
显式原型(prototype)
概念:每个函数上都有一个默认的 prototype 属性使您有能力向对象增加属性和办法。
function people(name) {
this.name = name;
this.say = function () {console.log(`hello!我是 ${name}`);
};
}
people.prototype.kungfu = function () {console.log(` 我是 ${this.name},我会中国功夫 `);
};
const qad = new people('秦爱德');
const zs = new people('张三');
console.log(qad);
console.log(qad.say());
console.log(qad.kungfu());
console.log(zs);
console.log(zs.say());
console.log(zs.kungfu());
以上代码创立了一个 people
构造函数,在它外部增加了一个 name
属性和 say
办法,在它的原型上增加了一个 kungfu
办法
如何了解外部属性和原型属性呢?
这里咱们能够借助 css
款式来便于了解
<style>
.test{font-size:24px}
</style>
<p style="color:red" class="test"> 哈哈 </p>
以上咱们创立了一个标签,并向标签增加了一个内联款式和内部款式,对齐构造函数的话,内联款式对应外部属性,是追随函数独有的,内部款式对应原型属性,能够是公共的,可在多处应用。
因为每次 new
一个新的构造函数,外部属性都会从新生成,而原型属性则不会,所以这也防止了内存上的节约。并且能够基于原型实现原型继承操作。
结构器(constructor)
概念:每个对象都会默认一个contructor
,并指向以后原型对象的构造函数。
console.log(qad.__proto__.constructor === people); // true
一图胜千言
总结:每个函数上都会自带一个 prototype 原型,在原型上增加的属性能够共用,函数即对象,对象自带属性 constructor 指向了这个构造函数
隐式原型(proto)
概念:每个对象都有一个 _proto_
属性,指向了创立该对象的构造函数的原型。
console.log(qad.__proto__ === people.prototype); // true
万事万物皆对象,函数也是一个对象,只有是对象,就领有 _proto_
属性,所以 _proto_
在结构器和原型之间建设了一个连贯,通过由外向外在结构器中找到原型的属性和办法。
原型链
当咱们创立了一个构造函数,并拜访外面的某一个属性时。会先从构造函数本身去找,再从显式原型(prototype
)下来找,再从隐式原型(__proto__
)下来找,再从 object
的__proto__
下来找,直到 null
。有值就返回相应的值,没有就返回undefined
,咱们把这个由外向外的查找过程称之为 原型链
一图胜千言
用好面向对象思维
下面提到咱们能够通过应用对象去构建事实世界的模型,并将简单问题简单化。要想使用好面向对象思维,咱们须要牢记面向对象的三大特色和几个准则
三大特色
1:封装
中华文化博大精深,将词语拆分之后,发现更好了解了
封:封存(将一系列行为、属性、业务逻辑等等封存起来)
装:包装(提供一个容器来寄存封存起来的代码,包装之后,对外输入)
封装外面还有一个概念叫做 形象,拆分之后也很好了解(把”像“的货色抽出来)
联合起来就是:咱们把类似雷同的一堆属性、行为、逻辑抽离进去,寄存到一个包装对象外面,管制好入参和出参便于别人调用,这就是封装。
2:继承
继:持续(持续延续下去)
承:承当(承当连续下来的重任,并发扬光大)
联合起来就是:子类持续沿用父类的行为或属性,并正当革新拓展业务,输入新的对象。颇有点子承父业,后来居上的意思。
3:多态
多:多种
态:状态 / 状态
联合起来就是:同一个实例对象在多种状态下有不同的展现状态
简略了解就是一个函数通过入参不同,能够失去不同的输入后果
几个准则
1:繁多职责准则
一个类或者一个函数实现性能要繁多,不能横七竖八,越纯正越好。一旦函数变得不纯正了,外部实现多个性能。当咱们在多处中央应用这个函数的时候往往会因为不够纯正而多写很多兼容代码。
2:凋谢关闭准则
一个类在拓展性不便应该是放弃凋谢的,对更改性应该是关闭的。比方咱们封装了一个函数,应该尽量预留好口子,以便日后新性能迭代,而防止间接更改之前曾经写好的代码。
3:里氏替换准则
里氏替换准则次要是用来束缚继承的,子类能够扩大父类的性能,但不能扭转父类原有的性能。如果子类不能残缺地实现父类办法,或者父类的某些办法在子类中曾经产生“畸变”,则倡议断开父子继承关系,采纳依赖、汇集、组合等关系来代替继承。
4:依赖倒置准则
下层模块不应该依赖于上层模块,两者都应该依赖其形象。简而言之就是面向接口开发,每个类都提供接口或者抽象类,抽象类往往是比较稳定的,当下层细节发生变化时,不应该间接影响下层。细节依赖于形象,只有形象不变,程序就不要变动。
5:组合聚合复用准则
在代码复用时,要尽量先应用组合或者聚合等关联关系来实现,其次才思考应用继承关系来实现。
6:高类聚低耦合
顾名思义就是高度相似的货色要汇集起来,低类似的货色不要将它们耦合到一起
js 自身就是一门面向对象编程的语言,在咱们的日常开发中,每时每刻都在享受着面向对象给咱们带来的编程体验。
感激
欢送关注我的集体公众号点击查看:前端有猫腻每天给你推送陈腐的优质好文。回复“福利”即可取得我精心筹备的前端常识大礼包。愿你一路前行,眼里有光!
感兴趣的小伙伴还能够加我点击查看:微信:yuyue540880 拉你进群,一起交换前端技术,一起游玩!