×

js继承的6种方式

js继承的6种方式(js中有哪些继承方式)

admin admin 发表于2024-06-16 08:56:10 浏览18 评论0

抢沙发发表评论

大家好,如果您还对js继承的6种方式不太了解,没有关系,今天就由本站为大家分享js继承的6种方式的知识,包括js中有哪些继承方式的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始吧!

本文目录

js中有哪些继承方式

继承的方式一共有三种:一、原型继承通过prototype 来实现继承。function Person(name,age) { this.name=name; this.age=age;}Person.prototype.sayHello=function(){alert (’’使用原型得到Name:’’ + this.name);} var per = new Person("马小倩",21);per.sayHello();//输出:使用原型得到Name:马小倩 function Student(){}Student.prototype=new Person("洪如彤",21); //实现原型继承var stu = new Student();Student.prototype.grade=5; Student.prototype.intr=function(){alert(this.grade);} stu.sayHello();//输出:使用原型得到Name:洪如彤stu.intr();//输出:5 二、构造函数实现继承function Person(name,age) { this.name=name; this.age=age;}Person.prototype.sayHello=function(){alert (’’使用原型得到Name:’’ + this.name);} var per = new Person("马小倩",21);per.sayHello();//输出:使用原型得到Name:马小倩三、 通过call、apply 实现继承

JS类的创建与继承

JS中,类的创建方式与函数的创建方式相同,主要区别在于一般我们创建类时,类名的首字母需要大写,同时,我们可以再类的原型上添加公共属性和方法。创建例子如下:     JS类的继承主要有6种方式:原型链继承、实例继承、组合继承、原型式继承、寄生继承、寄生组合继承     创建空的子函数,再子函数的原型上执行构造函数,让子函数的原型上拥有构造函数的全部属性和方法(包括构造函数的原型上的方法和属性),继承实现方法如下: 优点: 1.简单,子类实例既是子类的实例也是父类的实例             2.父类在原型上新增的方法和属性都能被子类获取到 缺点: 1.传参不方便,只能再继承的时候传递参数,无法在创建子类实例的时候传入参数             2.无法实现多继承(一个子类继承多个父类)             3.原型上的属性、方法被所有的实例共享     创建子类函数,在函数内部直接调用构造函数,如果构造函数有参数在这里传参,继承实现方法如下: 优点: 1.传参方便,可以在创建实例时传参             2.可以实现多继承 缺点: 1.无法继承父类原型上的属性和方法              2.因为原型上没有方法,所以无法实现函数复用         同时使用构造继承和原型链继承。继承实现方法如下: 优点: 1.综合了构造继承和原型链继承的优点,并且去除他们的缺点,总体而言是一个比较好的继承方案 缺点: 1.因为同时使用了原型链继承和构造继承,很明显可以看出父类实例的属性被调用了两次,浪费内存         创建一个函数传入要继承的父对象,内部创建空的子类函数,然后在子类函数外部将父对象赋值给子类函数的原型,再返回子类函数的new执行结果。继承实现方法如下:         函数内调用原型式继承,赋值给一个对象,然后可以自定义增加它的一些属性和方法。继承实现方法如下:         通过寄生方式,去掉父类的实例属性,在调用两次父类的构造的时候,就不会初始化两次实例方法或属性,避免的组合继承的缺点,也就是重新创建一个空的函数,将父类的原型拷贝给这个空函数,然后对子类函数执行这个空函数。继承实现方法如下: 优点:全身都是优点 缺点:实现复杂

JS面向对象三大特征:封装、继承、多态

把事物(属性和方法)封装在类(程序对象)中,隐藏事物的属性和方法的实现细节,仅对外公开接口。 1.构造函数模式

2.原型prototype封装

3.声明函数模式

4.工厂模式

5.闭包

一个对象可以使用另一个对象的属性和方法 (子类可以使用父类的属性和方法) 1.原型链继承

2.借用构造函数

这样就避免了原型链继承中,构造函数中的属性或者方法被其他实例所改变的问题 :这里要注意call方法的执行顺序:

值会被覆盖,这个要注意!

3.组合继承 使用原型链实现对原型对象属性和方法的继承,借用构造函数实现对实例属性方法的继承 这样既通过在原型上定义方法实现了函数复用,又能保证每个实例都有自己的属性

4.寄生式继承 寄生式继承是与原型式继承紧密相关的一种思路,它创造一个仅用于封装继承过程的函数,在函数内部以某种方式增强对象,最后再返回对象。

5.寄生组合式继承

不同对象与同一操作产生不同结果。把“想做什么”跟“谁去做”分开,把过程化的条件语句转换为对象的多态性,从而消除条件分支语句。有重写跟重载: 重写:子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。 重载:函数或者方法有相同的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者方法。

关于JS实现继承的方法都有哪一些

定义一个父类:// 定义一个动物类function Animal (name) {// 属性this.name = name || ‘Animal’;// 实例方法this.sleep = function(){console.log(this.name + ‘正在睡觉!’);}}// 原型方法Animal.prototype.eat = function(food) {console.log(this.name + ‘正在吃:’ + food);1.原型链继承核心:将父类的实例作为子类的原型function Cat(){}Cat.prototype = new Animal();Cat.prototype.name = ‘cat’; // Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.eat(‘fish’));console.log(cat.sleep());console.log(cat instanceof Animal); //trueconsole.log(cat instanceof Cat); //true特点:1.非常纯粹的继承关系,实例是子类的实例,也是父类的实例 2.父类新增的原型方法、属性,子类都能访问到 3.简单,易于实现缺点:1.要想为子类新增属性和方法,必须要在new Animal()这样的语句之后执行(可以在cat构造函数中,为Cat实例增加实例属性)2.无法实现多继承3.来自原型对象的引用属性被所有实例共享 4.创建子类实例时,无法向父类构造函数传参下面代码解释缺点3(注意是引用属性):function Super(){ this.val = 1; this.arr = ;}function Sub(){ // ...}Sub.prototype = new Super(); // 核心var sub1 = new Sub();var sub2 = new Sub();sub1.val = 2;sub1.arr.push(2);alert(sub1.val); // 2alert(sub2.val); // 1alert(sub1.arr); // 1, 2alert(sub2.arr); // 1, 22.构造继承核心:使用父类的构建函数来增强子类实例,等于复制父类的实例属性给子类(没用到原型),除了call方法,也可以用apply()function Cat(name){Animal.call(this);this.name = name || ‘Tom’;}// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // falseconsole.log(cat instanceof Cat); // true特点:1.解决了1中,子类实例共享父类引用属性的问题 2.创建子类实例时,可以向父类传递参数 3.可以实现多继承(call多个父类对象)缺点:1.实例并不是父类的实例,只是子类的实例 2.只能继承父类的实例属性和方法,不能继承原型属性和方法 3.无法实现函数复用,每个子类都有父类的实例函数的副本,影响性能3.实例继承核心:为父类实例添加新特性,作为子类实例返回function Cat(name){var instance = new Animal();instance.name = name || ‘Tom’;return instance;}// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); // false特点:1.不限制调用方式,不管是new 子类()还是子类(),返回的对象都具有相同的效果缺点:1.实例是父类的实例,不是子类的实例2.不支持多继承4. 拷贝继承核心:使用for…in将父类实例中的方法赋给子类实例unction Cat(name){var animal = new Animal();for(var p in animal){Cat.prototype;}Cat.prototype.name = name || ‘Tom’;} // Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // falseconsole.log(cat instanceof Cat); // true特点:1.支持多继承缺点:1.效率较低,内存占用高(因为要拷贝父类的属性)2.无法获取父类不可枚举的方法(for in无法访问不可枚举的方法)5.组合继承核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用function Cat(name){Animal.call(this);this.name = name || ‘Tom’;}Cat.prototype = new Animal(); //组合继承需要修复构造函数的指向Cat.prototype.constructor=Cat;// Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); // true特点:1.弥补了方式2的缺陷,可以继承实例属性、方法,也可以继承原型属性、方法2.既是子类的实例,也是父类的实例3.不存在引用属性的共享问题4.可传参5.函数可复用缺点:1.调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)6.寄生组合继承核心:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点function Cat(name){Animal.call(this);this.name = name || ‘Tom’;}(function(){// 创建一个没有实例方法的类var Super = function(){};Super.prototype = Animal.prototype;//将实例作为子类的原型Cat.prototype = new Super();//寄生组合继承需要修复构造函数的指向Cat.prototype.constructor=Cat;})(); // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); //true特点:1.堪称完美缺点:1.实现较为复杂 (BY三人行慕课)

请说明javascript的继承机制和java继承机制的区别

一,先来说说javascript的继承机制的几种方式:1,原型链继承:优点:从instanceof关键字来看,实例既是父类的实例,又是子类的实例,看起来似乎是最纯粹的继承。缺点:子类区别于父类的属性和方法,必须在Sub.prototype = new Base();这样的语句之后分别执行,无法被包装到Sub这个构造器里面去。例如:Sub.prototype.name = “sub”;无法实现多重继承。2,构造继承:优点:可以实现多重继承,可以把子类特有的属性设置放在构造器内部。缺点:使用instanceof发现,对象不是父类的实例。3,实例继承:优点:是父类的对象,并且使用new构造对象和不使用new构造对象,都可以获得相同的效果。缺点:生成的对象实质仅仅是父类的实例,并非子类的对象;不支持多继承。4,拷贝继承:优点:支持多继承。缺点:效率较低;无法获取父类不可枚举的方法。二,java继承机制:1,java里的类不能多重继承,如果一个类一旦继承了它的父类,那么它就别想再继承别的类。一个儿子只能有一个老爸,原本设计是没错的。可是在实际应用中,就会出现各种问题。2,java里有更好的接口,接口从本质上来说可以更好的代替继承。实现像C++里一样的宏定义的功能,把你想要的东西都抽象在接口里,让具体的类去实现这些功能。三,综上可以看出java不能多继承,javascript可以,但是javascript没有接口这一说话,也有局限性,各有千秋吧。

js继承的几种方式 各

js继承用的还是比较少的,一般通过原型链继承或混合继承目的就是降低创建对象的开销!

各种继承示例如下:

构造函数继承:

《script》    //把父类方法放到其原型链中而非类声明体中,以便每次实例化子类时不至于都执行函数而增加创建对象的开销    Person.prototype.speakP=function(){        console.log("I’m a Person!");    };    function Person(age,name) {        this.age = age;        this.name=name;    }    function Student(sno,age,name) {        Person.call(this,age,name);        this.sno = sno;    }    var s = new Student(95001,23,"小红");    console.log(Student.prototype.constructor);    //s.speakP(); //s不是Person类型,所以不能调用speakP函数;如果非要调用,可使用以下方案二:原型链继承《/script》

原型链继承:

《script》  Person.prototype.speakP=function(){        console.log("I’m a Person! age="+this.age+" name="+this.name);//通过实例化的子类对象调用我时获取不到父类的age、name    };    function Person(age,name) {        this.age = age;        this.name=name;    }    Student.prototype = new Person();    //因为修改了Student原型链,需要把其原型链上构造器重新指向自己    Student.prototype.constructor = Student;    function Student(sno,age,name) {        this.sno = sno;    }    var s = new Student(95001,23,"小红");    console.log(Student.prototype.constructor);    s.speakP();《/script》

混合继承:

《script》    Person.prototype.speakP=function(){        console.log("I’m a Person! age="+this.age+" name="+this.name);    };    function Person(age,name) {        this.age = age;        this.name=name;    }    Student.prototype = new Person();    Student.prototype.constructor = Student;    function Student(sno,age,name) {        Person.call(this,age,name);        this.sno = sno;    }    var s = new Student(95001,23,"小红");    console.log(Student.prototype.constructor);    s.speakP();《/script》

ES6 extends继承:

《script》   class Person {       constructor(age, name) {           this.age = age;           this.name = name;       }       sayHi(){           console.log("I’m a Person! age="+this.age+" name="+this.name);       }   }   class Student extends Person{       constructor(sno,age,name) {           super(age, name);           this.sno = sno;       }   }   var s = new Student(95001,24,"小红");   console.log(Student.prototype.constructor);   s.sayHi();《/script》

昌平北大青鸟分享JavaScript六种继承方式

继承是面向对象编程中又一非常重要的概念,JavaScript支持实现继承,不支持接口继承,实现继承主要依靠原型链来实现的。

原型链

首先得要明白什么是原型链,昌平北大青鸟建议可以在一篇文章看懂proto和prototype的关系及区别中讲得非常详细

原型链继承基本思想就是让一个原型对象指向另一个类型的实例

添加方法

在给SubType原型添加方法的时候,如果,父类上也有同样的名字,SubType将会覆盖这个方法,达到重新的目的。但是这个方法依然存在于父类中。

记住不能以字面量的形式添加,因为,上面说过通过实例继承本质上就是重写,再使用字面量形式,又是一次重写了,但这次重写没有跟父类有任何关联,所以就会导致原型链截断。

问题

单纯的使用原型链继承,主要问题来自包含引用类型值的原型。

借用构造函数

此方法为了解决原型中包含引用类型值所带来的问题。

这种方法的思想就是在子类构造函数的内部调用父类构造函数,可以借助apply()和call()方法来改变对象的执行上下文

传递参数

借助构造函数还有一个优势就是可以传递参数

JS继承之extends

ES6中有关 class 的继承方式,引入了 extends 关键字。 但其本质仍然是 构造函数 + 原型链的 组合式继承。

上述 B 类 (class)通过 extends 关键字,继承了 A 类 的所有属性和方法。 A 类 中的所有方法默认是添加到 B 的原型上,所以 extends 继承的实质仍然是原型链。

super 这个关键字,既可以当作函数使用,也可以当作对象使用。当作函数使用时 super 代表父类的构造函数,并在子类中执行 Parent.apply(this) ,从而将父类实例对象的属性和方法,添加到子类的 this 上面。

特别注意

因为类必须通过 new 关键字调用,所以在类的构造函数中 new.target 的值永远不会是 undefined 。

关于js继承的6种方式到此分享完毕,希望能帮助到您。