继承再理解

function Super(){
    this.name = ‘man‘;
    this.arr = [1,2,3]
}
var a = new Super();
a.name = ‘woman‘;
a.arr.push(4);
console.log(a.name);   // woman
console.log(a.arr);  // [1,2,3,4]
var b = new Super();
console.log(b.name);  // man
console.log(b.arr);  // [1,2,3]

 在没有继承的情况下,new出来的实例深度复制了构造函数中的属性

function SuperClass(){
  this.name = "women";
  this.bra = ["a","b"];
}
function SubClass(){
  this.subname = "your sister";
}
SubClass.prototype = new SuperClass();
var sub1 = new SubClass();
sub1.name = "man";
sub1.bra.push("c");
console.log(sub1.name);//man
console.log(sub1.hasOwnProperty(‘name‘))  //true
console.log(sub1.bra);//["a","b","c"]
var sub2 = new SubClass();
console.log(sub2.hasOwnProperty(‘name‘))  //false
console.log(sub2.name);//woman
console.log(sub2.bra);//["a","b","c"]

证明了仅通过原型链继承的话,子类的实例共享子类的原型对象(也就是共享父类的实例,父类实例化了一次,也就是仅仅深拷贝了一次)

function SuperClass() {
  this.name = "women";
  this.bra = ["a", "b"];
}
function SubClass() {
  this.subname = "your sister";
  //将SuperClass的作用域赋予当前构造函数,实现继承
  SuperClass.call(this);
}

var sub1 = new SubClass();
sub1.bra.push("c");
console.log(sub1.bra);//["a","b","c"]
var sub2 = new SubClass();
console.log(sub2.bra);//["a","b"]
function SuperClass() {
  this.name = "women";
  this.bra = ["a", "b"];
}
SuperClass.prototype.sayWhat = function(){
  console.log("hello");
}
function SubClass() {
  this.subname = "your sister";
  SuperClass.call(this);
}
var sub1 = new SubClass();
console.log(sub1.sayWhat());//TypeError: undefined is not a function

而通过借用构造函数的方法来继承的话,每个子类的实例中都有了父类构造函数的属性(深拷贝),但要是方法在构造函数中的化,那就造成浪费内存,没有实现方法的服用,

而且仅通过这种方式实现继承的化,父类的原型中的方法继承不到;

function SuperClass() {
  this.name = "women";
  this.bra = ["a", "b"];
}
SuperClass.prototype.sayWhat = function(){
  console.log("hello");
}
function SubClass() {
  this.subname = "your sister";
  SuperClass.call(this);       //第二次调用SuperClass
}
SubClass.prototype = new SuperClass(); //第一次调用SuperClass
var sub1 = new SubClass();
console.log(sub1.sayWhat());//hello

因此可以通过原型链 + 借用构造函数实现:每个子类的实例中都有了父类构造函数的属性(深拷贝,然后每个子类实例跟父构造函数拥有相同的属性,因此仅查找它自身,而不会     沿着原型链去查找,从而实现了改变自身不影响别人),而要复用的,一般是方法,就放在原型对象上。

时间: 2024-10-10 02:44:42

继承再理解的相关文章

继承的理解---开始

一,概念理解 1. 继承可以理解为即由基类产生派生类的这一过程.如人类(基类),学生(派生类),小学生(更低一级派生类). 2. 继承的派生类将拥有基类和自己的数据和行为. 二,继承规则 1.继承可以传递,object类为所有类的基类. 2.派生类应当是对基类的扩展.派生类无法去除已经继承的成员定义. 3.构造函数和析构函数不能被继承. 4.派生类如果定义了与继承而来的成员同名的新成员,就可以覆盖已继承的成员.但这并不因为这派生类删除了这些成员,只是不能再访问这些成员.我们可以使用new修饰符来

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

一.序言 ??和其他面向对象的语言(如Java)不同,Javascript语言对类的实现和继承的实现没有标准的定义,而是将这些交给了程序员,让程序员更加灵活地(当然刚开始也更加头疼)去定义类,实现继承.(以下不讨论ES6中利用class.extends关键字来实现类和继承:实质上,ES6中的class.extends关键字是利用语法糖实现的) Javascript灵活到甚至可以实现接口的封装(类似Java中的Interface和implements). 二.类的实现 1.我对类的理解 ??首先,

PLSA模型的再理解以及源码分析

PLSA模型的再理解以及源码分析 之前写过一篇PLSA的博文,其中的收获就是知道PLSA是LSA在概率层面的扩展,知道了PLSA是一种主题模型,知道了PLSA中的参数估计使用的是EM算法.当时我就认为,这样子经典好用的算法,我是会回头再来理解它的,这样子才会有更加深刻的心得.所以有了这篇PLSA模型的再理解. 1. 两种思路解PLSA模型 参考了很多资料,发现大体上有两种解决PLSA模型的思路.下面我们大致说一下它们的思路. 思路一:EM算法中需要更新两个概率 PLSA模型的示意图如下: 其中包

【Linux 驱动】设备驱动程序再理解

学习设备驱动编程也有一段时间了,也写过了几个驱动程序,因此有对设备驱动程序有了一些新的理解和认识,总结一下.学习设备驱动编程也有一段时间了,也写过了几个驱动程序,因此有对设备驱动程序有了一些新的理解和认识,总结一下. ★什么是驱动程序 刚开始学习设备驱动程序的时候,产生了许多的问题.什么是驱动程序?驱动程序是干嘛的?它是如何工作的?它又是如何跟操作系统联系起来的?一系列的问题,现在有些地方还是不一定清楚,但是相比起刚开始的那个阶段,感觉自己还是清楚了很多. 设备驱动程序说白了(实质)就是为应用程

再理解Windows程序内部运行机制

参照孙鑫<VC++深入详解> 创建Win32程序的步骤: 1. 编写WinMain函数 2. 设计窗口类(WNDCLASS) 3. 注册窗口类 4. 创建窗口 5. 显示并更新窗口(ShowWindow(hwnd,SW_SHOWNORMAL);UpdateWindow(hwnd);) 6. 消息循环(不断地从消息队列中取出消息,并进行响应) 7. 窗口过程函数(处理发送给窗口的消息) 测试代码如下(在VS2010编译通过): #include <stdafx.h> #include

再理解HDFS的存储机制

再理解HDFS的存储机制 1. HDFS开创性地设计出一套文件存储方式,即对文件分割后分别存放: 2. HDFS将要存储的大文件进行分割,分割后存放在既定的存储块(Block)中,并通过预先设定的优化处理,模式对存储的数据进行预处理,从而解决了大文件储存与计算的需求: 3. 一个HDFS集群包括两大部分,即NameNode与DataNode.一般来说,一个集群中会有一个NameNode和多个DataNode共同工作: 4. NameNode是集群的主服务器,主要是用于对HDFS中所有的文件及内容

再理解RankNet算法

再理解RankNet算法 前面的一篇博文介绍了学习排序算法(Learning to Rank)中的RankNet算法.如下: http://blog.csdn.net/puqutogether/article/details/42124491 那次的入门对其中的算法流程和基本原理没有深入了解,这次看自动摘要提取算法的时候,里面有一个排序单元,使用到的就是学习排序算法中的RankNet,这个时候才理解了.这就说明,有的时候回过头来看某些算法,你的认识会加深的. 好了,这次主要说一下RankNet这

【C语言学习】指针再理解(一)

★内存和地址 内存的基本单位是字节,那么内存就可以按字节进行编址,就是给组成内存的所有连续的字节安排地址.其中一个最恰当的比喻就是房子与门牌号,假设有20间连续的房子,从最左边(或者左右边)开始分配门牌号1~20,给内存中字节分配的地址就相当于门牌号,字节就相当于房间.字节的容量只能存储一个字符.那么,内存是如何存储比字符更大的数据呢,比如:整型数据.浮点型数据? ★更大的内存单元 为了存储更大的数据,就会把两个字节或者跟多的字节合在一起组成更大的内存单元.比如内存可以以"字"为单位来

hdu1240/poj2225 BFS广搜的再理解

原题地址 HDUOJ POJ 题目介绍 题意 这同样是一道搜索题,所不同的是要搜索的图是三维的而不是二维的.但这并没什么大的改变,只是增加了两个搜索的方向而已. 陷阱 要注意的地方是,所给出的起点终点的坐标是按照 列,行,层的顺序. 关于BFS 与DFS不同,BFS能保证所搜到的路径一定是最短路径,所以我们不需要维护一个多维(此处为3维)数组来记录访问到每一点的最小步数,只需要维护一个多维数组来标记是否走过就可以了.DFS中是要不停回溯来找最短路径的,但是BFS是不需要的.这是BFS本身的性质所