JS实现OO机制
一、简单原型机制介绍
继承是OO语言的标配,基本所有的语言都有继承的功能,使用继承方便对象的一些属性和方法的共享,Javascript也从其他OO语言上借鉴了这种思想,当一个函数通过"new"创建出一个实例后,那么这个实例就拥有这个函数的prototype对象所有的属性和方法,从而实现所有的实例都能共享一组实例和方法,Javascript所谓的类就行通过修改这个prototype对象实现的,以区别其他的原生对象,及自定义类
<script>
function A(){}
A.prototype={
a:"a",
fun:function () {}
}
var a=new A();
var b=new A();
alert(a.a===b.a);//true
alert(a.fun===b.fun)//true
</script>
总结:
1、我们将定义在原型上的方法(属性)叫做原型方法,原型方法(属性)被所有的实例所共享
2、但是我们不能加所有的属性和方法都定义到原型上,JS为了实现差异化,允许我们将方法和属性定义到构造函数内部,这叫做特权方法(属性)。
3、因此我们把共享的属性和方法放到原型内,把私有的数据放到构造函数里面。
function A() {
var count=0;
this.a=1;
this.fun=function () {
}
}
A.prototype={
b:1,
fun1:function () {}
}
var a=new A();
var b=new A();
alert(a.a);//输出1
alert(a.count);//输出undefined
4、当我们把方法和属性定义于this上面,那么外界还是能访问到,所以当方法(属性)是特有属性(方法),那么别置于this之下,之间定义到构造函数内部,并用var修饰,这是它就是名副其实的私有属性。
function A(){
var count=1;
this.a=666;
this.fun=function () {
}
}
A.prototype={
a:"aaa",
b:666666,
fun:function () {
}
}
var a=new A();
var b=new A();
alert(a.a===b.a);//输出:true 因为a是基本类型所以比较值
alert(a.fun===b.fun);//输出:false 比较引用
alert(a.a);//输出:666 说明特权属性会覆盖原型属性,当两个属性名一样的时候
delete a.a;
alert(a.a);//输出:aaa 删除特权属性后,输出原型属性
5、特权方法(属性)只是遮住原型方法(属性),只要使用delete 删除,就又能访问到原型属性
二、OO静态方法实现
<script>
function A(){}
A.a=function () {
alert(1);
}
A.a();//输出:1;
</script>
三、OO继承的实现
上面介绍了原型模式的用法,我们给prototype定义了什么方法和属性,那么对应的实例就会共享prototype中的方法和属性,那么当我们将A对象的prototype属性赋给B对象时,那么B对象就拥有了所有的A对象中原型中的属性和方法。
function A(){}
A.prototype={
a:666
}
function B(){}
B.prototype=A.prototype;
var b=new B();
alert(b.a);//输出:666
由于引用着同一个对象,这意味着,我们修改A对象的原型,那么B对象的原型也会受到影响,因此我们不能把同一个对象赋给两个类,所以这个问题需要解决
方法一:通过for in把父类的原型属性和方法一一的赋给子类的原型
//通过继承拷贝来实现继承,缺点是无法通过instanceof来判断实例类型
function extend(destination,source){
for(var prototype in source){
destination[prototype]=source[prototype];
}
return destination;
} function A(){}
A.prototype={
a:666
}
function B(){}
var b=extend(A,new A());
alert(b.a);//输出:666
方法二:子类的原型不从父类的原型那里直接获得,而是通过一个中间函数,将父类的原型赋值给该函数,然后这个函数的实例作为子类的原型
/**
* 解决通过prototype赋值型继承的应用同一个对象的问题
* @constructor
*/ //通过中间函数来解决
function A(){}
A.prototype={
a:666
}
function Bridge(){}
Bridge.prototype=A.prototype; function B(){}
B.prototype=new Bridge(); var a=new A();
var b=new B();
alert(A.prototype==B.prototype);//说明他们的原型被分开
alert(a.a===b.a);//输出:true 子类共享父类的原型属性(方法)
//为父类动态添加方法
A.prototype.lala=function(){
alert(1);
}
b.lala();//输出:1 子类获得了这个方法 B.prototype.lele=function () {
alert(2);
}
//a.lele();//error 父类不具有子类的方法 alert(b instanceof A);//true
alert(b instanceof B);//true
方法二:能通过instanceof的验证,现在es5就自带了这种方法来实现原型继承。这种方法还有另外一种简介的实现Object.Creat
<script>
/**
* 继承2的简洁版,通过一个方法来实现继承
* @param o 父类的原型
* @returns {F} 中间函数的原型
*/
Object.create=function (o) {
function F() {}
F.prototype=o;
return new F();
}
</script>
JS实现OO机制的更多相关文章
- 关于js内部运行机制的一本好书
读<单页Web应用一书>,第二章讲了js内部运行机制,感觉棒极了.之前读<你不知道的js>,看的云里雾里,似懂非懂.没想到单页Web一书将此内容讲的如此通俗易懂,好多困惑已久的 ...
- JS的解析机制
JS的解析机制,是JS的又一大重点知识点,在面试题中更经常出现,今天就来唠唠他们的原理.首先呢,我们在我们伟大的浏览器中,有个叫做JS解析器的东西,它专门用来读取JS,执行JS.一般情况是存在作用域就 ...
- JS的运行机制
代码块: JS中的代码块是指由<script>标签分割的代码段.JS是按照代码块来进行编译和执行的,代码块间相互独立(即就算代码块1出错,但不影响代码块2的加载和执行),但变量和方法共享. ...
- 试着讲清楚:js代码运行机制
一. js运行机制 js执行引擎 经常看文章的说到js是带线程的,其实这个说法非常的模糊,准确的是js执行引擎是单线程的,js执行引擎就是js代码的执行器,有了这个概念就可以下来说说js是如何运行的了 ...
- 浅析JS异步执行机制
前言 JS异步执行机制具有非常重要的地位,尤其体现在回调函数和事件等方面.本文将针对JS异步执行机制进行一个简单的分析. 从一份代码讲起 下面是两个经典的JS定时执行函数,这两个函数的区别相信对JS有 ...
- js事件循环机制辨析
对于新接触js语言的人来说,最令人困惑的大概就是事件循环机制了.最开始这也困惑了我好久,花了我几个月时间通过书本,打代码,查阅资料不停地渐进地理解他.接下来我想要和大家分享一下,虽然可能有些许错误的 ...
- 前端面试:谈谈 JS 垃圾回收机制
摘要: 不是每个人都回答的出来... 最近看到一些面试的回顾,不少有被面试官问到谈谈JS 垃圾回收机制,说实话,面试官会问这个问题,说明他最近看到一些关于 JS 垃圾回收机制的相关的文章,为了 B 格 ...
- python垃圾回收机制:引用计数 VS js垃圾回收机制:标记清除
js垃圾回收机制:标记清除 Js具有自动垃圾回收机制.垃圾收集器会按照固定的时间间隔周期性的执行. JS中最常见的垃圾回收方式是标记清除. 工作原理 当变量进入环境时,将这个变量标记为"进入 ...
- 深入理解 JS 引擎执行机制(同步执行、异步执行以及同步中的异步执行)
首先明确两点: 1.JS 执行机制是单线程. 2.JS的Event loop是JS的执行机制,深入了解Event loop,就等于深入了解JS引擎的执行. 单线程执行带来什么问题? 在JS执行中都是单 ...
随机推荐
- 使用ffmpeg将海康视频rtsp转为hls
测试环境: Ubuntu14.04 LTS Desktop ffmpeg version 3.3.3 命令行运行: ffmpeg -i rtsp://admin:12345@10.0.10.19:55 ...
- JavaScript语言精粹 笔记05 正则表达式
正则表达式 正则表达式以方法的形式被用于对字符串中的信息进行查找.替换画图提取操作.可处理正则表达式的方法有:regexp.exec, regexp.test,string.match, string ...
- strncmp用法说明
函数原型 int strcmp(char *str1,char * str2,int n) 功能 比较字符串str1和str2的前n个字符. 头文件 #include <string.h> ...
- java学习(七)java中抽象类及 接口
抽象类的特点: A:抽象类和抽象方法必须用abstract关键字修饰. B:抽象类中不一定有抽象方法,但是抽象方法的类必须定义为抽象类 c: 抽象类不能被实例化,因为它不是具体的. 抽象类有构造方法, ...
- Django Manage File
default_storage >>> from django.core.files.base import ContentFile >>> from django ...
- Python【filter、map、reduce】
filter和map和reduce map(function,iterable...) -> list 映射,对列表中的每个值操作 返回操作后的数值组成列表 # 给列表值+1 l = [1,2, ...
- c# 委托与事件的区别
委托与事件的区别 委托和事件没有可比性,因为委托是数据类型,事件是对象(可以理解为对委托变量的封装.),下面说的是委托的对象(用委托方式实现的事件)和(标准的event方式实现)事件的区别.事件的内部 ...
- 201621123012《Java程序设计》第10次学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 1. 常用异常 结合题集题目7-1回答 1.1 自己以前编写的代码中经常出现 ...
- Linux下iptables防火墙用法规则详解
管理网络流量是系统管理员必需处理的最棘手工作之一,我们必需规定连接系统的用户满足防火墙的传入和传出要求,以最大限度保证系统免受×××.很多用户把 Linux 中的iptables当成一个防火墙,从严格 ...
- Windows 操作系统如何使程序开机自启
Windows 操作系统如何开机自启 一.前言: 作为一只运维开发,很多时候需要将自己的小工具做开机自启.在 Linux 的世界里,如果你希望一个程序可以开机自启,那么可以在/etc/rc.d/rc. ...