读《JavaScript面向对象编程指南》(二)
第五章 原型
- 在JavaScript中,所有函数都会拥有一个 prototype 的属性,默认初始值为空对象。
- 可以在相关的原型对象中添加新的方法和属性,甚至可以用自定义对象来完全替换掉原有的原型对象。
- 通过某个构造器函数来new一个对象时,这些对象就会自动拥有一个指向 prototype 属性的 __proto__链接,通过它可以访问相关原型对象的属性。
- 对象自身属性的优先级要高于其原型对象的同名属性。
- 扩展内建对象不是一个好主意,如果必须要采用的话一定要谨慎。
- 当我们对原型对象执行完全替换时,可能会触发原型链某种异常,prototype.constructor属性是不可靠的。
- Best Practice:当我们重写某对象的prototype时,重置相应的constructor属性是一个好习惯。
- 每个对象都会有一个isprototype()方法,这个方法会告诉我们当前对象是否是另一个对象的原型。
- 神秘的__proto__链接。
枚举属性




参考链接:JavaScript for...in循环。
第六章 继承
//6.1.1 原型链示例
//6.1.2 将共享属性迁移到原型中去
//6.2 只继承于原型
function Shape(){ }
Shape.prototype.name = 'shape';
Shape.prototype.toString = function(){
return this.name;
}
function TwoDShape(){ }
TwoDShape.prototype = Shape.prototype;
TwoDShape.prototype.constructor = TwoDShape;
TwoDShape.prototype.name = '2D shape'; function Triangle(side, height){
this.side = side;
this.height = height;
}
Triangle.prototype = TwoDShape.prototype;
Triangle.prototype.constructor = Triangle;
Triangle.prototype.name = 'Triangle';
Triangle.prototype.getArea = function(){
return this.side * this.height / 2;
}
//临时构造器 new F()
function Shape(){ }
Shape.prototype.name = 'shape';
Shape.prototype.toString = function(){
return this.name;
}
function TwoDShape(){ }
var F = function(){};
F.prototype = Shape.prototype;
TwoDShape.prototype = new F();
TwoDShape.prototype.constructor = TwoDShape;
TwoDShape.prototype.name = '2D shape'; function Triangle(side, height){
this.side = side;
this.height = height;
}
var F = function(){};
F.prototype = TwoDShape.prototype;
Triangle.prototype = new F();
Triangle.prototype.constructor = Triangle;
Triangle.prototype.name = 'Triangle';
Triangle.prototype.getArea = function(){
return this.side * this.height / 2;
} //6.3 uber——子对象访问父对象的方式
function Shape(){}
Shape.prototype.name = 'shape';
Shape.prototype.toString = function(){
var result = [];
if (this.constructor.uber){
result[result.length] = this.constructor.uber.toString();
}
result[result.length] = this.name;
return result.join(', ');
}
function TwoDShape(){ }
var F = function(){};
F.prototype = Shape.prototype;
TwoDShape.prototype = new F();
TwoDShape.prototype.constructor = TwoDShape;
TwoDShape.uber = Shape.prototype;
TwoDShape.prototype.name = '2D shape'; function Triangle(side, height){
this.side = side;
this.height = height;
}
var F = function(){};
F.prototype = TwoDShape.prototype;
Triangle.prototype = new F();
Triangle.prototype.constructor = Triangle;
Triangle.uber = TwoDShape.prototype;
Triangle.prototype.name = 'Triangle';
Triangle.prototype.getArea = function(){
return this.side * this.height / 2;
} // 6.4 将继承部分封装成函数
function extend(Child, Parent){
var F = function(){};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.uber = Parent.prototype;
}
extend(TwoDShape, Shape);
extend(Triangle, TwoDShape); //6.5 属性拷贝
function extend2(Child, Parent){
var p = Parent.prototype;
var c = Child.prototype;
for (var i in p){
c[i] = p[i];
}
c.uber = p;
} //6.6 小心处理引用拷贝
//6.7 对象之间的继承
function extendCopy(p){
var c = {};
for(var i in p){
c[i] = p[i];
}
c.uber = p;
return c;
} //6.8 深拷贝
function deepCopy(c, p){
var c = c || {};
for (var i in p){
if (typeof p[i] === 'object'){
c[i] = (p[i].constructor === Array) ? [] : {};
deepCopy(c[i], p[i])
}else{
c[i] = p[i];
}
}
return c;
}
//6.9 object(),Douglas Crockford为我们提出了一个建议,既可以用object()
//函数来接受父对象,并返回一个以该对象为原型的新对象。
function object()(o){
var n;
function F(){}
F.prototype = o;
n = new F();
n.uber = o;
return n;
} //6.10 原型继承于属性拷贝的混合使用
function objectPlus(o, stuff){
var n;
function F(){};
F.prototype = o;
n = new F();
n.uber = o; for(var i in stuff){
n[i] = stuff[i];
}
return n;
} //6.11 多重继承
function multi(){
var n = {}, stuff, j = 0, len = arguments.length;
for(j = 0; j < len; j++){
stuff = arguments[j];
for(var i in stuff){
n[i] = stuff[i];
}
}
return n;
} //6.12 寄生式继承
var twoD = {
name : '2D shape',
dimensions : 2
}
function triangle(s, h){
var that = object(twoD);
that.name = 'Triangle';
that.getArea = function(){
return this.side * this.height / 2
};
that.side = s;
that.height = h;
return that;
} //6.13 构造器借用
function Shape(id){
this.id = id;
}
Shape.prototype.name = 'shape';
Shape.prototype.toString = function(){
return this.name;
}
function Triangle(){
Shape.apply(this, arguments);
}
Triangle.prototype = new Shape();
Triangle.prototype.name = 'Triangle';
//消除双重继承
function Shape(id){
this.id = id;
}
Shape.prototype.name = 'shape';
Shape.prototype.toString = function(){
return this.name;
}
function Triangle(){
Shape.apply(this, arguments);
}
function extend2(Child, Parent){
var p = Parent.prototype;
var c = Child.prototype;
for (var i in p){
c[i] = p[i];
c.uber = p;} }
extend2(Triangle, Shape);
Triangle.prototype.name = 'Triangle';
读《JavaScript面向对象编程指南》(二)的更多相关文章
- Java并发编程的艺术(二)——重排序
当我们写一个单线程程序时,总以为计算机会一行行地运行代码,然而事实并非如此. 什么是重排序? 重排序指的是编译器.处理器在不改变程序执行结果的前提下,重新排列指令的执行顺序,以达到最佳的运行效率. 重 ...
- Java并发编程的艺术(三)——volatile
1. 并发编程的两个关键问题 并发是让多个线程同时执行,若线程之间是独立的,那并发实现起来很简单,各自执行各自的就行:但往往多条线程之间需要共享数据,此时在并发编程过程中就不可避免要考虑两个问题:通信 ...
- 《Java并发编程的艺术》读书笔记:二、Java并发机制的底层实现原理
二.Java并发机制底层实现原理 这里是我的<Java并发编程的艺术>读书笔记的第二篇,对前文有兴趣的朋友可以去这里看第一篇:一.并发编程的目的与挑战 有兴趣讨论的朋友可以给我留言! 1. ...
- 读《Java并发编程的艺术》(一)
离开博客园很久了,自从找到工作,到现在基本没有再写过博客了.在大学培养起来的写博客的习惯在慢慢的消失殆尽,感觉汗颜.所以现在要开始重新培养起这个习惯,定期写博客不仅是对自己学习知识的一种沉淀,更是在督 ...
- 那些年读过的书《Java并发编程实战》和《Java并发编程的艺术》三、任务执行框架—Executor框架小结
<Java并发编程实战>和<Java并发编程的艺术> Executor框架小结 1.在线程中如何执行任务 (1)任务执行目标: 在正常负载情况下,服务器应用 ...
- 读《Java并发编程的艺术》学习笔记(一)
接下来一个系列,是关于<Java并发编程的艺术>这本书的读书笔记以及相关知识点,主要是为了方便日后多次复习和防止忘记.废话不多说,直接步入主题: 第1章 并发编程的挑战 并发编程的目的是 ...
- 读书笔记之《Java 并发编程的艺术》
一.多线程语义 即使是单核处理器也支持多线程执行代码,CPU 通过给每个线程分配 CPU 时间片来执行任务,当前任务执行一个时间片后会切换到下一个任务,所以 CPU 通过不停的切换线程执行. 并发执行 ...
- Java并发编程的艺术读书笔记(2)-并发编程模型
title: Java并发编程的艺术读书笔记(2)-并发编程模型 date: 2017-05-05 23:37:20 tags: ['多线程','并发'] categories: 读书笔记 --- 1 ...
- Java并发编程的艺术(六)——线程间的通信
多条线程之间有时需要数据交互,下面介绍五种线程间数据交互的方式,他们的使用场景各有不同. 1. volatile.synchronized关键字 PS:关于volatile的详细介绍请移步至:Java ...
- 《Java并发编程的艺术》留给自己以后看的笔记
<Java并发编程的艺术>这本书特别好,和<深入了解JAVA虚拟机>有一拼,建议做java的都看看,下面全部都是复制书中的部分内容,主要目的是做个笔记,方便以后遇到问题能找到. ...
随机推荐
- Tomcat服务org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.OutOfMemoryError: Java heap space
一个运行了很久的项目,最近忽然报错:OOM( java.lang.OutOfMemoryError: Java heap space),异常如下 org.springframework.web.uti ...
- MUT值设置、top等命令无法执行、ssh无法登陆、vim命令卡住
[root@host---- ~]# ifconfig eth0: flags=<UP,BROADCAST,RUNNING,MULTICAST> mtu inet 10.1.1.204 n ...
- mybatisplus EntityWrapper 常用方法
1. #WHERE (issue_type = ?) AND (status = ? OR status = ? OR status = ?) EntityWrapper wrapper=new En ...
- centos 7.3镜像制作
1.在KVM环境上准备虚拟机磁盘 [root@localhost ~]# qemu-img create -f qcow2 -o size=50G /opt/CentOS-7-1511-x86_64_ ...
- 利用netsh命令设置IP地址/DNS服务器地址
一.设置IP地址 1. 自动获取IP地址: netsh interface ip set address [name=]"本地连接" [source=]dhcp 2. 手动设置IP ...
- HanLP-分类模块的分词器介绍
最近发现一个很勤快的大神在分享他的一些实操经验,看了一些他自己关于hanlp方面的文章,写的挺好的!转载过来分享给大家!以下为分享原文(无意义的内容已经做了删除) 如下图所示,HanLP的分类模块中单 ...
- Series与list
一.索引 1.1 索引顺序 list的索引为从0到n-1.不可更改索引. Series的索引:如果未定义为从0到n-1.如果定义,则为定义的索引,一旦定义完成,索引对象将不可更改.但是索引是可以改变的 ...
- 小菜鸟之JAVA面试题库1
四次挥手 客户端发送释放连接报文,关闭客户端到服务端的数据传输 服务端收到后,发送确认报文给客户端 服务端发送释放连接报文,关闭服务端到客户端的数据传输 客户端发送一个确认报文给服务端 ------- ...
- P2670 【扫雷游戏】
题面哦~~ lalala~~~ 这题数据并不大,最大不过100*100,所以果断穷举 其实本来我是想边读边做的,但读入是个问题. 主要思路呢,就是读完之后穷举一边,只要是炸弹,就把周围一圈8个加一遍 ...
- 树上选两点(使最短)树的直径+bfs
题意: 给你一颗树,让你放两个点,放在哪里的时候任意点到某个最近的消防站最远值最小. 思路: 树的直径类题目. 首先我们想两个点会把整棵树分成两个团,所以肯定会在树的某个链上切开. 而且要切一定切在树 ...