封装
1、封装的概念
所谓封装,就是指隐藏内部的细节,不暴露在外面。
把构造函数里的this改成 _price;
在js里面,实现封装的方法非常简单,只需要在声明属性的时候,添加关键字即可。 一般来讲,对于私有属性,有一个不成文的规定,习惯使用_来命名属性。
封装后的属性(私有属性)对于外部来讲,虽然不可见,但是对于内部来讲,是可见的。
总结:封装后方法可以访问,但是属性信息都为undefined
2、get和set 以及属性特性
很多时候,我们对对象的属性进行封装,并不是为了外部访问不到,而是为了当外部访问对象属性或者设置的时候进行一定的限制。也就是说,外部能够正常的访问到进行限制了的属性。
Object.defineProperty(),通过这个方法可以给对象添加属性。
语法:Object.defineProperty(obj,prop,descriptor)
obj:目标对象
prop:需要添加到属性
descriptor:属性相关特性
descriptor参数是一个JSON对象,可以设置特性如下:
value:属性的值. //或者return。和 writable 一起用 默认false
writable:属性是否可写
get:一旦目标属性被访问的时候,就调用该方法
set:一旦目标属性被设置的时候,就调用该方法
enumerable:查看属性是否可以枚举,就是is hi 用for..in的时候,是否可以遍历出来。 True false
如果要设置多个属性,可以调用object.object.defineProperties(),这样就可以设置多个属性。使用该方法接收的参数也是有一定变化的
语法:object.defineProperties(obj,{JSON})
JSON对象 {prop:{descriptor},prop:{descriptor},…. }
for(let I in stu)
{
console.log(i);
}
继承
1、继承基本介绍
在程序语言里面,面向对象种所指的继承就是一个子类去继承一个父类。子类在继承了父类之后,父类所拥有的属性和方法自动就都拥有了。
继承的好处:
继承最大的好处,就在于代码能够进行复用。例如有两个类,就给他们写个父类。
继承缺点:
首先如果我们继承设计得非常复杂,那么整个程序设计也会变得庞大和复杂。
如果是像C++那样的多继承语言,那么可能还会出现菱形继承的问题。 //只有c++是多继承。改动之后 最下层方法不知道用哪一个
单继承:只有一个父类
多继承:有多个类
菱形继承问题:首先需要说明,菱形继承问题只会在多继承里面才会出现。
例如:a和b是继承base类,假设base类有一个成员方法,那么a和b都会有这个成员方法,这个时候a和b又分别对成员方法进行了修改。接下来让一个c来同时继承a和b,问题来了,对于同名的方法,究竟使用哪一个,这就是所谓的菱形继承问题。这个是属于设计上的问题。
由于js是单继承语言,所以一定程度上避免了菱形继承的问题。
2、js里面实现继承的方法
(1)对象冒充
所谓对象冒充,就是指用父类(构造函数)去充当子类的属性
temp=构造函数名字
但是,使用对象冒充实现的继承有一个缺点,缺陷就是无法继承到原型对象上面的属性或者方法
从对象冒充又衍生出来了一种通过call或者apply来实现继承,本质上还是对象冒充。
他俩基本上一样,只是参数接收不同
function.call(abj,arg1,arg2,arg3…)
Function.apply(obj,[arg1,arg2,arg3,arg4…])
Obj:代表当前对象
arg:代表一个参数列表
总结:简单来讲,就是将a所拥有的东西应用到b的环境里面,让b也拥有和a相同的东西,但是作用域还是b的,而不是a的。
c1.show.call(c2);
(2)通过原型对象来实现继承
这种方法的核心思路就是改变构造函数的prototype的属性值,但是这种方式也有一个缺点,就是无法传参
(3) 混合方式实现继承
为了实现能够同时传参以及能够继承到原型对象上面的属性和方法,采用上面两种方式的结合。
Person.call(this, name, age); //call 方法
Student.prototype = new Person();
(4)es6 实现继承的方式
埃ES6里面添加了关键字extends
class 子 extends 父 {
Constructor(name,age,gender,score){
super(name,age)
This..
}
}
super//访问父类
class Student extends Person { //extends关键字
constructor(name,age,gender,score){
super(name,age);//访问父类的内容
this.gender=gender;
this.score=score;
多态
1、什么事多态
所谓多态,就是指不同的对象的同名方法却有不同的效果,这就是多态。
最常见的多态即使to string();
虽然每个对象都有tostring()方法,但是并不是每一个对象的表现形式都一样的
转数组有逗号分隔
转数字 没有
2、实现多态
在继承父类当法的时候直接进行覆盖即可,这样就实现了多态。
(1)混合方式实现多态
给子类原型对象添加同名的方法;
调用同名方法。表现形式不一样。
(2)es6中实现多态
类里 方法也可以看作是一个属性
在子类里添加一个同名的属性进行调用
重写或重载。
我们重写
扩展
1、从对象创建对象
实际上在js里面创建对象时可以完全避免使用构造函数(或者说类,)而时使用另外一个对象作为原型来创建对象
使用
boject.create();
这个方法还可以传入第二个参数,第二个参数是json对象,用来对对象的属性设置相关特性。
2、混入
混入就是一种不需要继承,就将某些对象的属性和方法添加到另一个对象上面。通过Object.assing()来实现
语法:
Object.assign(target,a,b,c,d,…..)
Let a={ } ;
Let b={
name:”xiejie”,
age:18
}
let c={
gender:male;
score:100;
}
Object.assign(a,b,c);
Console .log(a.name);
如果混入对象中包含同名的属性,那么后面会覆盖前面的。
记住:混入优于继承
3、改写this的指向
this默认的指向:如果是全局环境或者函数里面调用,包括嵌套,这个this指向全局对象
Node global
浏览器 window
如果通过对象的方式来调用,那么this指向当前对象。
但是,这个this的指向,我们是可以改变的
(1)通过call或者apply可以改变this的指向
(2)通过bind()方法强行绑定this指向
(3)箭头函数的this
箭头函数基本语法
(形参)=>{函数体}
如果只有一个参数
形参=>{函数体}
这里与其数是箭头函数改变了this指向,更贴切的来讲,汗透函数的this指向和其他函数不一样,箭头函数的this指向始终是外部的作用域