原型

  1. 所有引用类型都有一个_proto_属性, 属性值是对象
  2. 所有函数都有一个prototype属性 , 属性值是一个对象
  3. 所有引用类型的_proto_属性 , 都指向其构造函数的prototype
  • _proto_是给浏览器使用的 , prototype是给程序员使用的
  • 原型的作用 : 数据共享, 节省空间
    在构造函数中定义的属性和方法,
    当实例化对象的时候,实例对象中的属性和方法都是在自己的空间中存在的,
    如果是多个对象, 这些属性和方法都会在单独的空间中存在,浪费内存空间,
    所以,为了数据共享,把想要节省空间的属性或者方法写在原型对象中,达到了数据共享,节省了内存空间。

constructor 构造函数

对象原型( proto)和构造函数(prototype)原型对象里面都有一个属性constructor
属性constructor我们称为构造函数,它指回构造函数本身
constructor主要用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数。

一般情况下,对象的方法都在构造函数的原型对象中设置。
如果有多个对象的方法,我们可以给原型对象采取对象形式赋值,
但是这样就会覆盖构造函数原型对象原来的内容,
这样修改后的原型对象constructor 就不再指向当前构造函数了。
此时,我们可以在修改后的原型对象中,添加一个 constructor指向原来的构造函数

如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数如:

function Star(uname, age) {this.uname = uname;this.age = age;}// 很多情况下,我们需要手动的利用constructor 这个属性指回 原来的构造函数Star.prototype = {// 如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用
constructor指回原来的构造函数constructor: Star, // 手动设置指回原来的构造函数sing: function() {console.log('我会唱歌');},movie: function() {console.log('我会演电影');}
}
var zxy = new Star('张学友', 19);
console.log(zxy)

原型链

当访问一个对象的属性时,
我们先去这个对象本身的属性去查找,
如果没有 就去这个对象的_proto_隐式属性查找, 其指向的是它构造函数的 prototype 属性
如果没有 再去这个构造函数的 __proto__ 查找 , 其指向这个构造函数的构造函数的 prototype
这就叫原型链

举例 :

function Parent(month){this.month = month;
}var child = new Parent('Ann');console.log(child.month); // Annconsole.log(child.father); // undefined


Object.prototype.__proto__ === null
一直往上层查找,直到到null还没有找到,则返回undefined

this指向

构造函数中的this和原型对象的this,都指向我们new出来的实例对象

继承

  1. JS没有像java的class那样的类
  2. 我们的构造函数 就类似java里的class
  3. 继承也是模拟继承
  4. 模拟继承是为了实现数据共享,节省内存空间。
  • 原型继承 子级.prototype = new 父级()
function Person(name, age, sex) { // 父级this.name = name;this.sex = sex;this.age = age;
}
Person.prototype.eat = function() {console.log("吃饭");
};
function Student(score) { //子级this.score = score;
}
Student.prototype = new Person("张三", 18, "男");//改变子级的原型的指向即可让子级继承父级
Student.prototype.study = function() {console.log("studing");
};
var stu = new Student(99);// 继承父级过来的属性和方法:
console.log(stu.name); // 张三
console.log(stu.age); // 18
console.log(stu.sex); // 男
stu.eat(); // 吃饭// 子级自带的属性和方法:
console.log(stu.score); // 99
stu.study(); // studing

利用原型继承的弊端 :
我们改变原型指向的同时,直接初始化了属性,这样继承过来的属性的值都是一样的了。
这是个问题,如果我们想要改变继承过来的值,只能重新调用对象的属性进行重新赋值,这又导致我们上边的初始化失去了意义。
所以我们有call 继承

  • 利用call()继承

call() 用来调用函数

call() 可以修改this的指向,使用call()的时候 第一个参数是修改后的this指向,后面的参数 使用逗号隔开连接

 function fn(x, y) {console.log(this);console.log(x + y);
}var o = {name: 'andy'  };fn.call(o, 1, 2);//调用了函数此时的this指向了对象o,

  • 组合继承

既用原型继承 又用call()继承

这样 既可以保证每个实例都有它自己的属性,又能做到对一些属性和方法的复用。

//父级
function Person(name) {this.name = name;
}
Person.prototype.sayHi = function() {console.log("你好");
};
//子级
function Student(name, score) {Person.call(this, name); //借用call()函数:解决属性值重复的问题this.score = score;
}
//改变原型指向 : 原型继承解决原型方法不能被继承问题
Student.prototype = new Person(); //不传值
Student.prototype.study = function() {console.log("studing");
};
var stu1 = new Student("张三", "100分");
console.log(stu1.name, stu1.score);
stu.sayHi();
stu.study();
var stu2 = new Student("李四", "99分");
console.log(stu2.name, stu2.score);
stu2.sayHi();
stu2.study();
  • for in 拷贝继承

把一个对象中的属性或者方法直接复制到另一个对象中
新对象通过拷贝函数原型prototype对象中的属性和方法继承prototype对象的属性和方法

下面这个例子 :

Person中有原型prototype,prototype就是一个对象,那么里面,name,age,sex,height,play都是该对象中的属性或者方法

function Person() {}
Person.prototype.name = "张三";
Person.prototype.age = 18;
Person.prototype.sex = "男";
Person.prototype.height = 180;
Person.prototype.study = function() {console.log("studing");
};
var obj = {};
for (var k in Person.prototype) { //for in 拷贝prototype的属性和方法obj[k] = Person.prototype[k];
}
console.dir(obj);
obj.study();

参考原文
【原型和原型链】什么是原型和原型链
ES6基础2-- 构造函数和原型
JavaScript 进阶教程(3)—让你彻底搞懂原型链和继承

JavaScript (四) ——构造函数原型 , 原型链 和继承相关推荐

  1. 深入理解Javascript中构造函数和原型对象的区别

    在 Javascript中prototype属性的详解 这篇文章中,详细介绍了构造函数的缺点以及原型(prototype),原型链(prototype chain),构造函数(constructor) ...

  2. javascript面向对象系列第一篇——构造函数和原型对象

    前面的话 一般地,javascript使用构造函数和原型对象来进行面向对象编程,它们的表现与其他面向对象编程语言中的类相似又不同.本文将详细介绍如何用构造函数和原型对象来创建对象 构造函数 构造函数是 ...

  3. JS中对象的四种继承方式:class继承、原型链继承、构造函数继承、组合继承(构造函数和原型链继承的结合)

    前言 才发现之前没有对JavaScript中的继承做过总结,不过看得到是不少,接下来就对这几种继承方式做一下总结. class继承 class继承是ES6引入的标准的继承方式. ES6引入了class ...

  4. JavaScript进阶-编程思想、构造函数的原型对象、对象原型、原型继承以及原型链

    编程思想 面向过程 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次 调用就可以了. 优点: 性能比面向对象高,适合跟硬件联系很紧密 的东西,例如单 ...

  5. 对Javascript 类、原型链、继承的理解

    一.序言   和其他面向对象的语言(如Java)不同,Javascript语言对类的实现和继承的实现没有标准的定义,而是将这些交给了程序员,让程序员更加灵活地(当然刚开始也更加头疼)去定义类,实现继承 ...

  6. JavaScript 设计模式学习第五篇-继承与原型链

    JavaScript 是一种灵活的语言,兼容并包含面向对象风格.函数式风格等编程风格.我们知道面向对象风格有三大特性和六大原则,三大特性是封装.继承.多态,六大原则是单一职责原则(SRP).开放封闭原 ...

  7. JavaScript 原型链和继承面试题

    JavaScript 原型链和继承问题 JavaScript 中没有类的概念的,主要通过原型链来实现继承.通常情况下,继承意味着复制操作,然而 JavaScript默认并不会复制对象的属性,相反,Ja ...

  8. JavaScript:原型链、继承

    1.理解原型对象 我们先使用构造函数创建一个对象: function Person() { } var person = new Person(); person.name = 'Kevin'; co ...

  9. JavaScript原型链实现继承

    js 继承 原型链 默认的原型 确定原型和实例的关系 谨慎定义方法 原型链的问题 借用构造函数 组合继承 最常用的继承模式 原型式继承 寄生式继承 寄生组合式继承 是引用类型最理想的继承范式 学习记录 ...

最新文章

  1. 「倚天」一出,谁与争锋!全球首款5nm服务器芯片,业界最强
  2. 机器人大牛 Daniela Rus 领衔!MIT 新算法实现软体机器人「本体感知」
  3. python找最大值的函数_Python 获取最大值函数
  4. Go语言初探gRPC服务
  5. psa name_Windows 10安全性PSA:启用自动商店更新
  6. java idle 机制_HotSpot VM重量级锁降级机制的实现原理
  7. 故障闪烁过渡网页幻灯片特效源码
  8. 重拾阅读--朝花夕拾啊
  9. sed -i 单引号中嵌套双引号_【函数应用】IF函数的多层嵌套
  10. 理解 Memory barrier(内存屏障)【转】
  11. Basic Edit in vim
  12. 【C语言数据结构7】--串的实现
  13. sql 服务器时间修改时间,教您如何修改sql server时间
  14. 快速搭建自己的人脸识别系统
  15. 好好说话之unlink
  16. 智能文档处理IDP关键技术与实践-高翔
  17. 使用c语言实现三子棋游戏
  18. ajax怎么请求数据,简单快捷
  19. Centos 7 怎么都连不上手机阿阿阿阿Android Studio 怎么都检测不到真机啊还有关于git本地提交就缺少文件啊啊啊啊
  20. 麻将牌识别算法AI也能打麻将了只赢钱

热门文章

  1. 地图坐标转换 -- 火星坐标与GPS坐标
  2. 热烈祝贺黄手艺冒菜景德镇市珠山区陶阳南路东
  3. 微信小程序 | 02.微信原生框架的目录结构
  4. 一步一步改写Observer观察者模式
  5. C++11 bind取代bind1st,bind2nd的用法
  6. 屎上最全vue-pdf+Springboot与aspose-words整合,开箱即用
  7. Photoshop制作水晶球中的美女
  8. 平衡二叉树中点的数量
  9. Linux如何创建用户
  10. 读《春秋》有感之一:士会让贤