JS继承和原型链

一、类class

在es6中,可以使用class关键字声明一个类,之后以这个类来实例化对象。

类抽象了对象的公共部分,它泛指某一大类 对象特指某一个,通过实例化一个具体的对象

继承:子类可以继承父类的一些属性和方法

class Father{
           constructor(x,y){
            this.x = x;
            this.y = y;
           }
           sum(){
               console.log(this.x + this.y);
               console.log(this.x)
           }
           say(){
               return '我是爸爸'
           }
       }
       class Son extends Father{
        constructor(x,y){
            super(x,y);//调用了父类中的构造函数,必须在子类this之前调用
            this.x = x;
            this.y = y;
           
        }
        say(){
            console.log(super.say() + '的儿子')//super调用父类的普通函数
        }
       }
       var son = new Son(1,2)
       son.sum();
       son.say();

1.类的constructor构造函数
类里面有个constructor函数,可以接收传递过来的参数,同时返回实例对象
constructor函数只要new生成实例时,就会自动调用这个函数,如果不写constructor这个函数,类也会自动生成这个函数。
类的共有属性放在constructor里面
类里面所有的函数不用写function;也不加,分割
2.extends 让子类继承父类
super关键字:可以调用父类的constructor(构造函数),也可以调用父类的普通函数。
子类在构造函数(constructor)中使用super,必须放在this前面(必须先调用父类的构造函数,再使用子类构造方法)
3.继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的
继承中,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这个方法。(就近原则)
4.在es6中类没有变量提升,所以必须先定义类,才能通过类实例化对象
类里面的共有属性和方法一定要加this

二、构造函数

构造函数是一种特殊的函数,主要用来初始化对象(也就是为对象成员变量赋值),它总与new一起使用。我们可以把对象中一些公共属性和方法抽取出来,然后封装到这个函数里面。

实例成员:(函数内部通过this添加的成员)只能通过实例化的方法来访问
静态成员:(在构造函数本身上添加的成员)静态成员只能通过构造函数来访问

new在执行时做了什么?
(1)在内存中创建一个新的空对象

(2)让this指向这个新的对象

(3)执行构造函数里面的代码,给这个新对象添加属性和方法

(4)返回这个新对象(所以构造函数里不需要return)

 function Star(uname,uage){
           this.uname = uname;//实例成员
           this.uage = uage;
           this.sing = function(){
               console.log('我唱歌')
           }
       }
       var ldh = new Star('刘德华',20);
       console.log(ldh.uname);
       ldh.sing()//1.实例成员(函数内部通过this添加的成员)只能通过实例化的方法来访问
       //Star.sing()//报错

       Star.sex = '男';//2.静态成员(在构造函数本身上添加的成员)
       console.log(ldh.sex)//undefined
       console.log(Star.sex)//男   静态成员只能通过构造函数来访问

构造函数方法很好用,但是存在浪费内存的问题

构造函数中不变的方法在每次new一个实例的时候,都会在堆里面开辟一个空间。我们想让这个不变的方法只占一个空间,所以就有了构造函数原型。

三、构造函数原型prototype

JS规定每一个构造函数都有一个prototype属性,指向另一个对象。我们可以把那些不变的方法,直接定义在prototype对象上,这样所有对象的实例就可以共享这些方法。

四、es5继承与es6继承的区别

继承:子类可以继承父类的一些属性和方法
(1)Es5的继承实质是先创建子类的实例对象,然后再将父类的方法添加到this上(Father.call(this))。
Es6的继承实质是先创建父类的实例对象this,然后再用子类的构造函数修改this。
(2)Es5的继承通过构造函数和原型来实现
Es6通过class关键字定义类,类里面有构造方法,类之间通过关键字extends实现继承。子类必须在constructor方法中调用super方法,否则新建实例报错。因为子类没有自己的this对象,而是继承类父类的this对象,然后对其加工。如果不调用super方法,子类将得不到this对象。

五、es5定义一个类,并实现继承
组合继承
在这里插入图片描述

function Father(name,age){
        this.name = name;
        this.age = age;
    }
    Father.prototype.work = function(){//父亲的方法
        console.log('父亲工作')
    }
    function Son(name,age){
        Father.call(this,name,age)//继承父类的属性(在father中把this指向子构造函数的实例)
    }
    Son.prototype.study = function(){
        console.log('孩子上学')
    }
    Son.prototype = new Father();//继承父类的方法(直接赋值,修改了儿子原型对象的constructor)
    Son.prototype.constructor = Son;//把儿子的constructor修改回去
    var son = new Son('小明',18);
    console.log(son);
    console.log(son.__proto__.constructor)
    console.log(son instanceof Father);

寄生组合式继承
在这里插入图片描述

 function Father(name,age){
            this.name = name;
            this.age = age
        }
        Father.prototype.work = function(){
            console.log('父亲工作')
        }
        function Son(name,age){
            Father.call(this,name,age);//继承父类的属性
        }
        Son.prototype.study = function(){
            console.log('孩子上学')
        }
        Son.prototype = Object.create(Father.prototype);
        //继承父类的方法:先创建了一个临时的构造函数,然后将父亲的原型对象作为这个构造函数的原型,最后返回临时类型的新实例
        //然后让儿子的原型对象指向临时类型的新实例(这样就可以实现继承了)
        Son.prototype.constructor = Son;
        var son = new Son('aaa',23);
        console.log(Son.prototype);
        console.log(son.__proto__.constructor)

        object.create相当于下面的create函数(不用写)
        function create(obj) {
            function F() {}//先创建了一个临时的构造函数
            F.prototype = obj;//然后将传入的对象作为这个构造函数的原型
            return new F();//返回了临时类型的新实例
        }
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我来回答你的问题。以下是一些JS原型继承原型链的面试题及其答案: 1. 什么是原型继承? 答:原型继承是通过将一个对象的原型作为另一个对象的原型来实现继承。在JS中,每个对象都有一个原型,它可以通过__proto__属性来访问。 2. 什么是原型链? 答:原型链是一种通过原型继承来实现对象间继承关系的机制。当我们访问一个对象的属性时,JS会首先在该对象自身查找,如果没有找到,就会在它的原型对象上查找,如果还没有找到,就会在原型对象的原型对象上查找,一直到Object.prototype对象为止,这个查找的过程就是原型链。 3. 如何实现一个简单的原型继承? 答: ```javascript function Person(name) { this.name = name; } Person.prototype.sayHi = function() { console.log('Hi, my name is ' + this.name); } function Student(name, grade) { Person.call(this, name); this.grade = grade; } Student.prototype = Object.create(Person.prototype); Student.prototype.constructor = Student; Student.prototype.sayGrade = function() { console.log('My grade is ' + this.grade); } var tom = new Student('Tom', 3); tom.sayHi(); tom.sayGrade(); ``` 4. 如何判断一个对象是否是另一个对象的实例? 答:可以使用instanceof运算符来判断,例如: ```javascript var obj = {}; console.log(obj instanceof Object); // true ``` 5. 如何判断一个属性是在对象自身定义的还是继承自原型? 答:可以使用JS提供的hasOwnProperty方法来判断,例如: ```javascript var obj = {}; console.log(obj.hasOwnProperty('toString')); // false console.log(Object.prototype.hasOwnProperty('toString')); // true ``` 希望这些问题和答案能够帮助你更好地理解JS原型继承原型链

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值