1.prototype


我们可以简单的把prototype看做是一个模版,新创建的自定义对象都是这个模版(prototype)的一个拷贝 (实际上不是拷贝而是链接,只不过这种链接是不可见,给人们的感觉好像是拷贝)。

//'构造函数'a
function a(name){
  this.name = name
}

//原型属性,可共享
a.prototype.getName = function(){
  return this.name;
}

a.prototype.setName = function(name){
  this.name = name;
  return this.name;
}

var b = new a('zqz');

//--内部实现
//看上去像copy 其实就是改变了实例的指针到a原型上
//复制'成员属性','成员函数'
var _b = {
  getName:function(){
    return this.name;
  },
  setName:function(name){
    this.name = name;
    return this.name;
  }
}

//还有构造函数的指向为a
var b = _b;
//--end

//使用
b.getName() //=>zqz
b.setName('z')

b.getName() //=>z

-------------------

//把MyFn作为构造函数
function MyFn(){}
var a = new MyFn();

function MyFn(){}
var a = {}
MyFn.call(a) //将a对象作为this的指针调用MyFn函数

继承可以理解为一个对象从另一个对象获取属性的过程。

java:使用new创建对象时,会调用构造方法初始化对象。

constructor始终指向创建当前对象的构造函数

2.原型继承


左边跟右边都能实现方法的调用。
但是左边在每个实例对象的上创建一个个jiao对象副本。
而右边不会,因为不管new出多少对象。都只会共享原型上的一个jiao正本。

prototype提供了一群同类对象共享属性和方法的机制。

function Person(name){
  this.name = name;
}

Person.prototype.Say = function(){
  alert(this.name)
}

function Emp(name, sal){
  Person.call(this, name);
  this.sal = sal;
}

//这里的操作就是将Person这个类的方法跟属性复制一份出来给Emp的原型(原型上的Say是不会copy故去的,Say而是在Emp的原型链上)
//并且这时候Emp.prototype.constructor不再指向Emp这个构造函数,而是指向Person
//在原型模型中,为了实现类继承,必须首先将子类构造函数的prototype设置为一个父类的对象实例
Emp.prototype = new Person();

Emp.prototype.Show = function(){
  alert(this.name + '$' +this.sal)
}

见图:

这里我们只是需要这个原型__proto__,而不需要name这类成员属性,因为这些对于继承来说没什么用。

 3.多态性


对象可以覆盖原型对象的属性跟方法,但这钟覆盖其实是在自身对象上创建了新的属性和方法,只不过这些属性和方法与原型对象的同名而已。(原型上的其实并没有改变)

这中掩盖机制就是"多态"性。与静态语言的虚函数和重载不谋而合。
然后,更厉害的是,我们可以随之给原型对象动态添加新的属性和方法,从而动态的扩展基类的功能特性。

function Person(name){
  this.name = name;
}

Person.prototype.Say = function(){
  alert(this.name)
}

var xiaoming = new Person('小明')
xiaoming.Say()

var xiaohong = new Person('小红');

//小红实现自己的Say方法,不会覆盖Person上的Say
xiaohong.Say = function(){
  alert('我叫' + this.name)
}
xiaohong.Say();

随机推荐

  1. java线程 - 多线程 - 守护线程

    1.多线程执行者/处理类 都是Runnable的实现类(如自定义类实现Runnable 或 java原生的Thread.FutureTask),但最后都必须封装成Thread线程类由Thread.st ...

  2. SQL基本语句汇总

    语句:CREATE TABLE 作用:创建表格 格式:CREATE TABLE tableName (columnName1 columnDataType1, columnName2 columnDa ...

  3. .NET随记【你懂的】

    .NET随记.txt放在桌面好久了,编程过程中记录些杂七杂八的东西,分享给大家希望有所帮助. goto 常用于 switch语句中 字符串相加用 StringBuilder的Append()方法性能好 ...

  4. Extjs 表单验证后,几种错误信息展示方式

    今天要求对form表单验证,进行系统学习一下,故做了几个示例: Ext.onReady(function(){        var panel=Ext.create('Ext.form.Panel' ...

  5. Secret Codes

    Secret Codes   This is a list of codes that can be entered into the dialer to output the listed info ...

  6. 别出心裁的Linux系统调用学习法

    别出心裁的Linux系统调用学习法 操作系统与系统调用 操作系统(Operating System,简称OS)是计算机中最重要的系统软件,是这样的一组系统程序的集成:这些系统程序在用户对计算机的使用中 ...

  7. @Override的作用

    @Override是伪代码,表示重写(不写也可以,但是有些IDE会报warning),不过写上有如下好处: 1.可以当注释用,方便阅读:2.编译器可以给你验证@Override下面的方法名是否是你父类 ...

  8. 动态的计算行高 加载数据源 有多少显示多少 tableView 包含 colloctionView 显示复杂的界面写法

    有时候,我们经常碰到这样的需求 先遵守代理 @interface PublishCollectionCell ()<UICollectionViewDataSource, UICollectio ...

  9. HDU-1754I Hate It 线段树区间最值

    这道题比较基本,就是用线段树维护区间最值,可以算是模板吧-.. I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768 ...

  10. iOS Plist文件,增删改查

    今天早上,9点开始弄Plist,然后一直写,一直写(中午取出40分钟吃饭时间),写到1点,写完了,交给头,头说,不是这个意思.我是每个用户创建了一个文件夹,在这个用户的文件夹里面,分别根据应用创建了文 ...