读《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的都看看,下面全部都是复制书中的部分内容,主要目的是做个笔记,方便以后遇到问题能找到. ...
随机推荐
- 【转】Linux curl命令详解
[From]https://www.cnblogs.com/duhuo/p/5695256.html 命令:curl 在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具,可以说是一 ...
- Control的Invoke和BeginInvoke
转载:https://www.cnblogs.com/c2303191/articles/826571.html 近日,被Control的Invoke和BeginInvoke搞的头大,就查了些相关的资 ...
- jdk1.8-stack 栈源码分析
一:类的继承关系 UML图: 类的继承关系: )) { ) { ) );} 分析:栈的peek()方法,其实就是返回栈顶部的元素值,即数组末尾元素值. peek()方法只是返回下标的值,但并不删除该元 ...
- Jquery(DOM和选择器)
O(∩_∩)O~~~,今天简单整理了一下最近所学的Jquery知识.下面就总结一下. 首先,对于Jquery我们需要简单了解下: 1.Jquery是开放源代码的JS库, 2.Jquery操作是函数式编 ...
- Vuex的认识和简单应用(一)
一.vuex是一个专为vue.js应用程序开发的状态管理模式. 应用场景:1.多个视图依赖于同一个状态2.来自不同视图的行为需要变更同一个状态此时,我们可以把组件的共享状态抽取出来,以一个全局单例模式 ...
- 转-Uptime与数据中心等级认证
1 数据中心等级认证 随着数据中心的蓬勃发展,越来越多的标准被制定出具.其中,Uptime Tier认证在业内是认同度最高的标准.以前,Uptime在中国的宣传很少,很多人对Uptime及其认证体系不 ...
- Datafactory 实际使用案例
Datafactory 实际使用案例 一. 简介 QuestDataFactory 是一种快速的.易于产生测试数据工具,它能建模复杂数据关系,且有带有GUI界面.DataFactory是一 ...
- 一加手机2 进入recovery 模式无法挂载USB存储器通过命令窗口上传ROM镜像
试过3.0.3-0和3.0.3-1的recovery都无法使用“挂载USB大容量存储器”模式,这肯定让很多清掉系统(就是system分区)的小伙伴无力吐槽,因为这样子rom就无法在rec里面从电脑拷到 ...
- 【Python开发】matplotlib绘图不显示问题解决plt.show()
最近在看<Python数据分析>这本书,而自己写代码一直用的是Pycharm,在练习的时候就碰到了plot()绘图不能显示出来的问题.网上翻了一下找到知乎上一篇回答,试了一下好像不行,而且 ...
- Unity打包出来的App 跳转其他 App
void Start()//在android测试成功 { bool fail = false; string bundleId = "跳转的包名";//包名称 AndroidJav ...