对象2
面向对象的三大特征:1、封装 2、继承 3、多态
封装
- 概念:实现隐藏细节的过程。
- 好处:1、重用
- 2、隐藏实现的细节(可设置访问权限/级别)
- 不限于面向对象,无处不在
纯面向对象的访问级别:
- public 级别最低,均可访问
- protected 仅限父与子之间
- package 作用域,命名空间
- private 级别最高
JS都是public,都可访问;可模拟private;不需要protected、package
let Student=function(name,age){ this.name=name; // let age =age; 报错,age已定义; 局部变量 this.show=function(){ console.log('我是'+this.name); } } let stu1=new Stu('学生',20); stu1.show(); 或 let Student=function(name,age){ this.name=name; let_age=age; // let age =age; 报错,age已定义; 局部变量 this.show=function(){ console.log(`我是${this.name},今年¥{_age}岁); } } let stu1=new Stu('学生',20); console.log(stu1_age); stu1.show();
修改器 set, 访问器 get
let Student=function(name,age,sex){ this.name=name; this.age=age; this.sex=sex; this.show=function(){ console.log(`我是${this.name},今年${this.age}岁,性别${this.sex}`); } } 'name' 属性名,字符串 Object.defineProperty(Student.prototype,'name',{ //objec.defineProperty固定写法,Student.prototype设置set/get的对象 set:function(name){ // 最后单独设置了名字,进入这一句,输出改变后的名字和'我是set方法' console.log('我是set方法'); this._name=name; // _name 初始化,必须加下划线 }, // 作为参数,用逗号 get:function(){ // 不管最后有没有单独设置其他名字,因为有return,都要进入这一句,输出'我是get方法' console.log('我是get方法'); //可有可无 return this._name; } }); let stu1=new Student('vivi',22,'女'); console.log(stu1.name); stu1.name='json'; stu1.age=30; stu1.sex='man'; stu1.show();
继承
- 概念:一个类沿用了父类的属性、方法,并且可拥有自己的属性、方法的行为就是继承。
- 好处:1、重用 2、扩展(自己的东西)
- 缺陷:(零型?)继承
JS-单根继承,缺陷得到一定解决;es6以前JS没有继承方法
继承方法
1、对象冒充法
let People =function(name,age){ this.name=name; this.age=age; } People.prototype.into=function(){ // 方法;可继承共有的;into自己取的名字 console.log(`Hi,我是${this.name}`); } let ChinesePeople=function(name,age){ this.inhert=People; this.inhert=(name,age); // 不是继承,只是调用别人的 delete this.inhert; // delete 关键字 } let c1=new ChinesePeople("姓名",22); console.log(c1.name,c1.age); // 输出 姓名,20 c1.intro(); // 检测,输出 空; (1) console.log(c1.instanceof CinesePeople); // instanceof 检测;输出true; (2) console.log(c1.instanceof People); // 输出false;不是继承;(3)
call/apply区别:传参 call(参数列表) apply(数组)
同上 let ChinesePeople=function(name,age){ People.call(this,name ,age); People.apply(this[name,age]); } let c1=new CinesePeople("姓名",22);
2、原型链
- 把原来的原型改为另一对象,作为原型
- 能变成真的继承
- 缺陷:不能传值
同上 ... let c1=new ChinesePeople('姓名',22); console.log(c1.__proto__); // 访问原型;__proto__ 是2条下划线; ChinesePeople{}... console.log(c1.__proto__.__proto__.__proto__); //一级一级往上访问原型
3、混合方式
let ChinesePeople=function(name,age){ People.call(this,name,age); // 加入这句 } ChinesePeople.prototype = new People(); let c1 = new ChinesePeople("姓名",20); let c2 = new ChinesePeople("姓名",21); console.log(c1.name,c1.age); c1.intro(); console.log(c1 instanceof People);
prototype 和 proto 区别:
- prototype:1、构造函数的方法属性 2、可改变原型
- proto: 1、是每个函数的属性,通过对象依次往上找原型 2、不可改变原型,只能访问
总结
- 面向对象:把复杂问题简单化,更接近人类思维
- 对象本身是一种数据类型,包含很多属性的集合,方法也是属性
- es5:要初始化必须加_下划线封装
- 封装:运用 修改器set、访问器get , 必须写 Object.definePropertype;
-
例: Object.definePropertype(Teacher.prototype,'name'{ set:function(name){ this.name=name; }, // 作为参数,使用逗号 get:function(){ return this._name; } });
-
继承:1、对象冒充法不是继承,运用关键字delete,输出可用intro、intanceof检测
- 2、原型链:能变成真的继承,运用proto ,可一级一级访问原型,检测;但是不能传值
- 3、混合方式:加入 call 或 apply