JavaScript笔记——面向对象与原型
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);
JavaScript笔记——面向对象与原型的更多相关文章
- javascript笔记 面向对象
Javascript是一种面向对象的弱语言,既然有面向对象,就有继承 继承: 1.call函数和apply函数:区别在于它们参数上的不同,固定参数的用call,可变参数的用apply.换句话说,就是a ...
- javascript笔记—面向对象
什么是对象: 对象是一个整体,对外提供一些操作. 什么是面向对象: 使用对象时,只关注对象提供的功能,不关注其内部细节,例如jquery 面向对象是一种通用思想,并非只有编程中能用,任何事情都可以用. ...
- 我的JavaScript笔记--面向对象
单例模式 ??(基于对象,不能批量生产) var person = { name: "ywb", sayHi: funct ...
- 第一百零九节,JavaScript面向对象与原型
JavaScript面向对象与原型 学习要点: 1.学习条件 2.创建对象 3.原型 4.继承 ECMAScript有两种开发模式:1.函数式(过程化),2.面向对象(OOP).面向对象的语言有一个标 ...
- JavaScript的面向对象原理之原型链详解
一.引言 在16年的10月份,在校内双选会找前端实习的时候,hr问了一个问题:JavaScript的面向对象理解吗?我张口就说“JavaScript是基于原型的!”.然后就没什么好说的了,hr可能不知 ...
- javascript的基础知识及面向对象和原型属性
自己总结一下javascript的基础知识,希望对大家有用,也希望大家来拍砖,毕竟是个人的理解啊 1.1 类型检查:typeof(验证数据类型是:string) var num = 123; cons ...
- JavaScript高程第三版笔记-面向对象编程
之前有篇博客曾提到过一点js的面向对象编程:js面向对象编程. 这里就结合js高程详细剖析一下javascript的面向对象编程. 前序: 1⃣️Object.defineProperty() var ...
- [Effective JavaScript 笔记]第3章:使用函数--个人总结
前言 这一章把平时会用到,但不会深究的知识点,分开细化地讲解了.里面很多内容在高3等基础内容里,也有很多讲到.但由于本身书籍的篇幅较大,很容易忽视对应的小知识点.这章里的许多小提示都很有帮助,特别是在 ...
- [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象
js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...
随机推荐
- 开发常用js代码段
// 获取http传递的参数export const getRequest = ()=>{ var url = location.search; //获取url中"?"符后的 ...
- jenkins的Master/Slave模式
一. Master/Slave模式 分担jenkins服务器的压力,任务分配到其它执行机来执行 Master:Jenkins服务器 Slave:执行机(奴隶机).执行Master分配的任务,并返回任务 ...
- 扫描局域网中Gogs服务器(ruby)
scanGogs.rb #!/usr/bin/env ruby require 'net/http' require 'thread' require 'english' # config CONFI ...
- mongodb停止遇到shutdownServer failed: unauthorized: this command must run from localhost when running db without auth解决方法
停止mongodb use admin db.shutdownServer(); mongos> db.shutdownServer(); assert failed : unexpected ...
- 深入理解c/c++ 内存对齐
内存对齐,memory alignment.为了提高程序的性能,数据结构(尤其是栈)应该尽可能地在自然边界上对齐.原因在于,为了访问未对齐的内存,处理器需要作两次内存访问:然而,对齐的内存访问仅需要一 ...
- Slice header里面有哪些重要的参数?
first_mb_in_slice:第一个宏块在slice的位置 slice_type:slice的类型 pic_parameter_set_id:slice对应的pps的id frame_num:表 ...
- 最新海康摄像机、NVR、流媒体服务器、回放取流RTSP地址规则说明
本文档主要介绍海康威视设备预览.回放.流媒体取流的RTSP URL和IE直接预览.回放的HTTP URL. RTSP为取流协议,取到码流后需要解码显示,可以通过VLC播放器进行测试,IE等浏览器网页不 ...
- 使用Kali Linux执行中间人攻击(演示)
中间人攻击也叫Man-In-The-Middle-Attack. 我假设你已经知道中间人攻击的基本概念,引用一段wikipedia: 中间人攻击(Man-in-the-middle attack,缩写 ...
- phpcmsV9搜索分页数量
phpcmsV9搜索结果自定义控制分页条数,具体方法: 打开搜索模型文件夹phpcms/modules/search/index.php, 找到第85行: $result = $this->db ...
- BZOJ - 2141 排队 (动态逆序对,区间线段树套权值线段树)
题目链接 交换两个数的位置,只有位于两个数之间的部分会受到影响,因此只需要考虑两个数之间有多少数对a[l]和a[r]产生的贡献发生了变化即可. 感觉像是个带修改的二维偏序问题.(修改点$(x,y)$的 ...