对象—封装、继承

对象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
原文地址:https://www.cnblogs.com/llying/p/7528809.html