> 文档中心 > 【js面向对象第二天】 一、如何理解原型和原型链二、三种不同继承方式的优缺点 三、call()和apply()四,对象的私有属性

【js面向对象第二天】 一、如何理解原型和原型链二、三种不同继承方式的优缺点 三、call()和apply()四,对象的私有属性

目录

一、如何理解原型和原型链

二、三种不同继承方式的优缺点

三、call()和apply()

四,对象的私有属性



一、如何理解原型和原型链

Object 是所有对象的爸爸,所有对象都可以通过 __ proto__ 找到它;
Function 是所有函数的爸爸,所有函数都可以通过 __ proto__ 找到它;
函数的 prototype 是一个对象;
对象的 __ proto__ 属性指向原型, __ proto__ 将对象和原型连接起来组成了原型链

原型链继承案例代码:

 // 原型连继承    //创建构造函数 人类    function People(name, age) { this.name = name; this.age = age;    }    People.prototype.sleep = function() { console.log(this.name + "在睡觉"); return this;    }    People.prototype.eat = function() { console.log(this.name + "在吃饭") return this; //返回this,实现方法的链式调用    }    //创建学生类 并继承人类的属性和原型    function Student(name, age) { // 将people的this指向student的this 继承构造函数people的属性 People.call(this, name, age);    }    // 将构造函数people实例化的对象设置为student的原型,达到继承people的原型的效果    Student.prototype = new People("zhangsan", 20) // 设置学生类的study方法    Student.prototype.study = function() { console.log(this.name + "正在学习"); return this;    }//使用构造函数 学生类 创建一个学生对象 s1    var s1 = new Student("张三", 22)    s1.eat().study().sleep();    console.log(s1);

图解

 如图所示:

s1对象的_proto_属性指向它的构造函数Student的原型——Student.prototype

但是Student.prototype=new People(),所以s1的_proto_属性直接指向了构造函数function People创建的people对象,people对象中的_proto_属性又指向了它的构造函数的原型——people.prototype,而构造函数people原型中的_proto_属性直接指向了Object,Object中的_proto_属性指向null


二、三种不同继承方式的优缺点

 // 三种不同继承方式 //创建构造函数 人类 function People(name, age) {     this.name = name;     this.age = age; } People.prototype.sleep = function() {     console.log(this.name + "在睡觉");     return this; } People.prototype.eat = function() {     console.log(this.name + "在吃饭")     return this; //返回this,实现方法的链式调用 } // 1.原型链继承 : 将原型改成 对应的对象(要继承的构造函数创建的对象) //问题:无法初始化对应的属性 比如这里的name和age // 创建学生类 使用原型链继承法继承人类 function Student(name, age) { } Student.prototype = new People("张三", 22) Student.prototype.song = function() {  console.log(this.name + "正在唱歌");     }     // 创建两个学生对象 var s1 = new Student("王一", 20); var s2 = new Student("tom", 18); console.log(s1.name, s1.age, s2.name, s2.age) //张三 22   张三 22// s1,s2的name和age属性无法更改 // 2.冒充继承法:通过call或者apply改变原有函数的this指向  // 创建教师类 使用冒充继承法继承人类 // 将构造函数 人类的this指向当前构造函数 教师类的this function Teacher(name, age) {     People.call(this, name, age) } Teacher.prototype.teach = function() {     console.log(this.name + "正在讲课") } var t1 = new Teacher("李老师", 24) t1.teach() //李老师正在讲课 console.log(t1.name) //李老师     // t1.sleep() //Uncaught TypeError: t1.sleep is not a function // 缺点:无法继承原型中的方法和属性 // 3:组合继承: 原型链继承+冒充继承 //创建好学生类 并继承人类的属性和原型 // 优点:同时继承原型和属性,可以对属性初始化 function goodStudent(name, age) {     // 将people的this指向student的this 继承构造函数people的属性     People.call(this, name, age); } // 将构造函数people实例化的对象设置为student的原型,达到继承people的原型的效果 goodStudent.prototype = new People("zhangsan", 20)     // 设置学生类的study方法 goodStudent.prototype.study = function() {  console.log(this.name + "正在学习");  return this;     }     //使用构造函数 学生类 创建一个学生对象 s1 var s1 = new goodStudent("李四", 22) s1.eat().study().sleep(); console.log(s1.name);//李四


三、call()和apply()

1.共同点:都能改变this指向

2.区别:加入参数的方式不同

 // apply的参数:    // 第一个参数: 方法执行的时候, 方法中的this的指向     //     第二个参数: 方法执行的时候, 所有参数组成的一个数组-- > [];   test.call(obj,["hello"])

  // Math.max()  和 Math.min()方法 中都是放数值,数值之间用逗号隔开 var arr1 = [20, 13, 56, 34, 89]; var arr2 = [12, 13, 14, 78, 90]; console.log(Math.max(arr)) //NAN console.log(Math.max(20, 13, 56, 34, 89)) //89     // 使用apply()方法就可以在Math.max()  和 Math.min()方法中放入数组 console.log(Math.max.apply(null, arr2)); //90 var res = Math.min.apply(null, arr2); console.log(res); //12

四,对象的私有属性

面向对象编程特点:

    1.抽象性: 通过对象来分析具体问题

    2.封装性: 将属性和方法,全部都封装到对象中,便于维护 节约二次开发成本  安全

    3.继承性:将对象直接属性或者方法,进行传递 Java C python

    4.多态性:一个类 产生多种对象!!

 对象属性 :分为两种

        公有属性:可以任意访问 ,修改的

        私有属性:必须通过方法才能,访问或者修改   。

              一.需要一定安全性的属性 比如密码  

              二.有一定的校验规则

如何设置对象的私有属性?请看下面的代码

 function Person(name, age, ID) {     // 设置私有属性ID     var ID = ID;     this.name = name;     this.age = age;     // 获取ID的方法     this.getID = function() {  return ID;     };     // 修改ID的方法     this.setID = function(value) {  // 设置校验规则   var reg = /\d{6}$/;  if (reg.test(value)) {      ID = value;  } else {      alert("ID必须是六位数字组成!")  }     } } var p1 = new Person("小智", 18, 127346)     // 获取p1的ID console.log(p1.ID) //undefined console.log(p1.getID()) //127346 // 修改p1的ID p1.setID(238434) console.log(p1.getID()) //238434

【js面向对象第二天】 一、如何理解原型和原型链二、三种不同继承方式的优缺点 三、call()和apply()四,对象的私有属性 《新程序员》:云原生和全面数字化实践 【js面向对象第二天】 一、如何理解原型和原型链二、三种不同继承方式的优缺点 三、call()和apply()四,对象的私有属性 50位技术专家共同创作,文字、视频、音频交互阅读