JavaScript也是一门面向对象的语言。面向对象的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性和方法的对象。但是,JavaScript竟然没有class,因此它的面向对象也与其他的OOP语言有所不同,创建对象和继承关系都显得很怪异很复杂难用

创建对象

JavaScript也采用了构造函数的概念:

function Box(name, age) {   //构造函数模式
this.name = name;
this.age = age;
this.run = function () {
return this.name + this.age + '运行中...';
};
}
var box1 = new Box('Lee', 100);
var box2 = new Box('Jack', 200);
alert(box1.run());
alert(box1 instanceof Box); //很清晰的识别他从属于 Box

构造函数的方法有一些规范:

1.函数名和实例化构造名相同且大写,(非强制,但这么写有助于区分构造函数和普通函数)

2.通过构造函数创建对象,必须使用 new 运算符(构造函数和普通函数的唯一区别,就是他们调用的方式不同。构造函数也是函 数,必须用 new 运算符来调用,否则就是普通函数了)

构造函数示意图:

原型的概念

在创建类之前,先要有原型的概念,我们创建的每个函数都有一个 prototype(原型)属性,这个属性是一个对象,它的用途是 包含可以由特定类型的所有实例共享的属性和方法。简单地说原型就是实现共享的功能:比如说类里的方法和一些需要共享的属性(较少见)

function Box() {}    //声明一个构造函数
Box.prototype.name = 'Lee'; //在原型里添加属性
Box.prototype.age = 100;
Box.prototype.run = function () { //在原型里添加方法
return this.name + this.age + '运行中...';
};
var box1 = new Box();
var box2 = new Box();
alert(box1.run== box2.run); //true,方法的引用地址保持一致

在上面的run方法和name,age属性不论声明多少个对象都是相等的(共享了)

原型示意图:

在原型模式声明中,多了两个属性,这两个属性都是创建对象时自动生成的。__proto__ 属性是实例指向原型对象的一个指针,它的作用就是指向构造函数的原型属性 constructor。 通过这两个属性,就可以访问到原型里的属性和方法了。浏览器中无法获取其内部信息

原型的声明是有先后顺序的,所以,重写的原型会切断之前的原型

function Box() {};

Box.prototype = { //使用原型创建属性和方法
constructor : Box,
name : 'Lee',
age : 100,
run : function () {
return this.name + this.age + '运行中...';
}
}; Box.prototype = { //原型被重写了
age :200
};
var box = new Box();
alert(box.run()); //错误TypeError: box.run is not a function ,因为重写了原型,原来的原型方法,属性失效

创建类与对象

使用动态原型模式创建对象可以使方法成为共享的,而属性各是各的

//动态原型模式创建对象
function Box(name,age){
this.name=name;
this.age=age; if(typeof this.run!='function'){
Box.prototype.run=function(){ //使用原型来实现方法共享
return this.name+this.age+'运行时';
};
}
} var box1=new Box('lz',21);
var box2=new Box('Jack',20);
alert(box1.run());
alert(box2.run());

继承

继承是面向对象中一个比较核心的概念。其他正统面向对象语言都会用两种方式实现继承:一个是接口实现,一个是继承。而JavaScript只支持继承,不支持接口实现

推荐使用寄生组合继承的方式:

function obj(o) {           //传递一个字面量函数
function F() {} //创建一个构造函数
F.prototype = o; //把字面量函数赋值给构造函数的原型
return new F(); //最终返回出实例化的构造函数
} function create(box,desk){ //将来传入父类和子类
var f=obj(box.prototype); //将父类的原型传入
f.constructor=desk; //改变子类的constructor
desk.prototype=f; //又将f传给子类的原型
} function Box(name,age){ //父类
this.name=name;
this.age=age;
this.arr=['爸爸','妈妈','儿子'];
if(typeof this.run!='function'){
Box.prototype.run=function(){
return this.name+this.age+'运行时';
}
}
} function Desk(name,age){ //子类
Box.call(this,name,age); //对象冒充
} create(Box,Desk); //通过这里实现继承 //下面是证明不同子类对象互不影响(不同空间)
var desk=new Desk('lz',21);
desk.arr.push('女儿');
alert(desk.arr); var desk2=new Desk('jack',20);
alert(desk2.arr);

最新文章

  1. Windows下Git多账号配置,同一电脑多个ssh-key的管理
  2. Java_太阳系_行星模型_小游戏练习_详细注释
  3. Ext 修改Store初始化加载完后修改record属性。
  4. ACM ICPC 2015 Moscow Subregional Russia, Moscow, Dolgoprudny, October, 18, 2015 H. Hashing
  5. MVC 4 异步编程简化了
  6. Powershell学习之道-文件夹共享及磁盘映射
  7. ios之无限图片轮播器的实现
  8. nmap与ntop
  9. NGUI3.5系列教程之 UILabel
  10. 优化 MySQL 中的分页
  11. Keil C51中变量的使用
  12. vs2005编译QT4.5版本
  13. JS实现图片不间断滚动
  14. Go学习笔记02-源码
  15. maven入门(1-4)使用eclipse构建maven项目
  16. ANG-----全方位保障您的数字资产安全
  17. 运行 vue 报node错
  18. JavaScript 匿名函数
  19. (转)Nandflash读写
  20. 读取ViewBag匿名类

热门文章

  1. 新东方雅思词汇---7.4、cap
  2. python 爬虫003-正则表达式简单介绍
  3. Django进阶Model篇001 - mysql 数据库的配置
  4. Intellij IDEA 配置Subversion插件实现步骤详解
  5. jQ通过cookie记住用户名
  6. monkey 原理,环境搭建、命令详解
  7. Struts07---访问servlet的API
  8. Illumina Fastq Q-score
  9. Android onTouchEvent和setOnTouchListener中onTouch的区别
  10. Tinker爬坑之路