1、原型链继承

核心: 将父类的实例作为子类的原型

缺点:  父类新增原型方法/原型属性,子类都能访问到,父类一变其它的都变了

        function Person (name) {
this.name = name;
}; Person.prototype.getName = function () { //对原型进行扩展
return this.name;
}; function Parent (age) {
this.age = age;
}; Parent.prototype = new Person('老明'); //这一句是关键 //通过构造器函数创建出一个新对象,把老对象的东西都拿过来。 Parent.prototype.getAge = function () {
return this.age;
}; // Parent.prototype.getName = function () { //可以重写从父类继承来的方法,会优先调用自己的。
// console.log(222);
// }; var result = new Parent(22);
console.log(result.getName()); //老明  //调用了从Person原型中继承来的方法(继承到了当前对象的原型中)  
console.log(result.getAge()); //22   //调用了从Parent原型中扩展来的方法

2、构造继承

基本思想
借用构造函数的基本思想就是利用call或者apply把父类中通过this指定的属性和方法复制(借用)到子类创建的实例中。
因为this对象是在运行时基于函数的执行环境绑定的。也就是说,在全局中,this等于window,而当函数被作为某个对象的方法调用时,this等于那个对象。
call、apply 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。 所以,这个借用构造函数就是,new对象的时候(new创建的时候,this指向创建的这个实例),创建了一个新的实例对象,
并且执行Parent里面的代码,而Parent里面用call调用了Person,也就是说把this指向改成了指向新的实例,
所以就会把Person里面的this相关属性和方法赋值到新的实例上,而不是赋值到Person上面,
所以所有实例中就拥有了父类定义的这些this的属性和方法。 因为属性是绑定到this上面的,所以调用的时候才赋到相应的实例中,各个实例的值就不会互相影响了。

核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)

缺点: 方法都在构造函数中定义, 只能继承父类的实例属性和方法,不能继承原型属性/方法,无法实现函数复用,每个子类都有父类实例函数的副本,影响性能

      function Person (name) {
this.name = name;
this.friends = ['小李','小红'];
this.getName = function () {
return this.name;
}
}; // Person.prototype.geSex = function () { //对原型进行扩展的方法就无法复用了
// console.log("男");
// }; function Parent = (age) {
Person.call(this,'老明');  //这一句是核心关键
//这样就会在新parent对象上执行Person构造函数中定义的所有对象初始化代码,
// 结果parent的每个实例都会具有自己的friends属性的副本
this.age = age;
}; var result = new Parent(23);
console.log(result.name);    //老明
console.log(result.friends);  //["小李", "小红"]
     console.log(result.getName());  //老明
     console.log(result.age);    //23
     console.log(result.getSex());  //这个会报错,调用不到父原型上面扩展的方法

3、组合继承

组合继承(所有的实例都能拥有自己的属性,并且可以使用相同的方法,组合继承避免了原型链和借用构造函数的缺陷,结合了两个的优点,是最常用的继承方式)

核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后再通过将父类实例作为子类原型,实现函数复用

缺点:调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)

        function Person  (name) {
this.name = name;
this.friends = ['小李','小红'];
}; Person.prototype.getName = function () {
return this.name;
}; function Parent (age) {
Person.call(this,'老明');  //这一步很关键
this.age = age;
}; Parent.prototype = new Person('老明');  //这一步也很关键
var result = new Parent(24);
console.log(result.name);    //老明
result.friends.push("小智");  //
console.log(result.friends);  //['小李','小红','小智']
console.log(result.getName());  //老明
console.log(result.age);    //24 var result1 = new Parent(25); //通过借用构造函数都有自己的属性,通过原型享用公共的方法
console.log(result1.name);  //老明
console.log(result1.friends);  //['小李','小红']

4、寄生组合继承

核心:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点

缺点:堪称完美,但实现较为复杂

        function Person(name) {
this.name = name;
this.friends = ['小李','小红'];
} Person.prototype.getName = function () {
return this.name;
}; function Parent(age) {
Person.call(this,"老明");
this.age = age;
} (function () {
var Super = function () {}; // 创建一个没有实例方法的类
Super.prototype = Person.prototype;
Parent.prototype = new Super(); //将实例作为子类的原型
})(); var result = new Parent(23);
console.log(result.name);
console.log(result.friends);
console.log(result.getName());
console.log(result.age);

javascript 面向对象(实现继承的几种方式)的更多相关文章

  1. javascript中实现继承的几种方式

    javascript中实现继承的几种方式 1.借用构造函数实现继承 function Parent1(){ this.name = "parent1" } function Chi ...

  2. 深入理解JavaScript之实现继承的7种方式

    1.原型链继承 核心:将父类的实例作为子类的原型 首先,要知道构造函数.原型和实例之间的关系:构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个原型对象的指针. func ...

  3. javascript(js)创建对象的模式与继承的几种方式

    1.js创建对象的几种方式 工厂模式 为什么会产生工厂模式,原因是使用同一个接口创建很多对象,会产生大量的重复代码,为了解决这个问题,产生了工厂模式. function createPerson(na ...

  4. 前端知识体系:JavaScript基础-原型和原型链-实现继承的几种方式以及他们的优缺点

    实现继承的几种方式以及他们的优缺点(参考文档1.参考文档2.参考文档3) 要搞懂JS继承,我们首先要理解原型链:每一个实例对象都有一个__proto__属性(隐式原型),在js内部用来查找原型链:每一 ...

  5. js 实现继承的6种方式(逐渐优化)

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  6. js实现继承的5种方式 (笔记)

    js实现继承的5种方式 以下 均为 ES5 的写法: js是门灵活的语言,实现一种功能往往有多种做法,ECMAScript没有明确的继承机制,而是通过模仿实现的,根据js语言的本身的特性,js实现继承 ...

  7. [转]javascript指定事件处理程序包括三种方式:

    javascript指定事件处理程序包括三种方式: (1):DOM0级事件处理程序 如: 代码如下: var btn=document.getElementById("mybtn" ...

  8. JavaScript对象属性访问的两种方式

    JavaScript对象属性访问的两种方式 object.attribute object["attribute"] 例如: var employees = [ { "f ...

  9. js 实现继承的几种方式

    //js中实现继承的几种方式 //实现继承首先要有一个父类,先创造一个动物的父类 function Animal(name){ this.name = name; this.shoot = funct ...

随机推荐

  1. SQL数据库查询一张表新建一个排序字段并根据某列的排序存储排序值

    现在有一张表如下Id Name Age Classify Score1 张一 18 一班 122 张二 17 二班 19 3 张三 19 三班 30 我跟据他们的分数进行排名 再去新建一个列存储排序值 ...

  2. Nginx 安装--图片服务器搭建

    1.  nginx 需要依赖以下模块: gzip模块需要 zlib 库 rewrite模块需要 pcre 库 ssl 功能需要openssl库 1.1.安装pcre 1.         获取pcre ...

  3. DVWA1.9平台XSS小结

    LOW级别就不写了...... 直接上中高级别(结合源码更好理解) 1.XSS Reflected(Medium) 从源码中可以清楚的看到,输入的<script>标签被过滤掉了,看清了,只 ...

  4. SPOJ - AMR11

    A Thanks a lot for helping Harry Potter in finding the Sorcerer's Stone of Immortality in October. D ...

  5. Python学习 day04

    一.list list可以存放各种类型的数据,与java中list类差不多,比如li = ['keith', 1, True, [1, 2, 3], {name: 'tangtang', age: 1 ...

  6. oracle12C--新特性

    Orcle 12c 新特性-使用DBCA创建物理备库 >>点击这里<< Orcle 12c DG 新特性-Far Sync >>点击这里<< Orcle ...

  7. Java基础20-构造代码块

    特点: 对象一建立就运行了,而且优先于构造函数执行 作用:给对象初始化的 构造代码块和构造方法的区别: 构造方法是对应的对象进行初始化 构造代码块是给所有的对象进行统一的初始化 public clas ...

  8. (转)图解SSH原理

    图解SSH原理 原文:https://www.jianshu.com/p/33461b619d53 http://blog.51cto.com/forlinux/1352900---------SSH ...

  9. 第一章:hybrid app开发之技术选型

    伴随着移动互联网的兴起,越来越多的企业将部分资源投入其中,想在互联网+的大潮中分一杯羹,并期望着站在风口上,成为时代的弄潮儿. 现在不会做一个app都不好意思说是搞互联网的,那么开发一个app的方式有 ...

  10. 详细讲解Android的网络通信(HttpUrlConnection和HttpClient)

    前言,Android的网络通信的方式有两种:使用Socket或者HTTP,今天这一篇我们详细讲解使用HTTP实现的网络通信,HTTP又包括两种方式编程方式: (1)HttpUrlConnection: ...