读《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的都看看,下面全部都是复制书中的部分内容,主要目的是做个笔记,方便以后遇到问题能找到. ...
随机推荐
- 【转】Java IOUtils方式上传下载文件 on HDFS
[From]https://www.cnblogs.com/areyouready/p/9795442.html package com.css.hdfs04; import java.io.File ...
- java:常见问题(解决获取properties乱码,解决poi自适应宽度)
1.解决获取properties乱码 File cf = new File("D:\\app\\java_jar\\config.properties"); String[] pa ...
- list 属性字段直接转成字符串数组
List<Car> cars = //whatever; string concat = String.Join(",", cars.Select(c => c. ...
- convert.ToInt32和int.parse区别
前者适合将object类类型转换成int类型 int.Parse适合将string类类型转换成int类型 1)这两个方法的最大不同是它们对null值的处理方法:Convert.ToInt32(null ...
- Django-ORM之聚合和分组查询、F和Q查询、事务
聚合查询 聚合对查询的结果进行一步的计算加工. aggregate()是QuerySet 的一个终止子句 ,他的作用是,返回一个包含一些键值对的字典.键的名称是聚合值的标识符,值是计算出来的聚合值.键 ...
- c语言GCC mingw 64位安装
1.安装步骤和下载地址 一.MinGW简介 MinGW是是将GCC编译器和GNU Binutils移植到Win32平台下的产物,包括一系列头文件(Win32API).库和可执行文件.MinGW是从Cy ...
- 统计学习方法 | 第1章 统计学习方法概论 | Scipy中的Leastsq()
Scipy是一个用于数学.科学.工程领域的常用软件包,可以处理插值.积分.优化.图像处理.常微分方程数值解的求解.信号处理等问题.它用于有效计算Numpy矩阵,使Numpy和Scipy协同工作,高效解 ...
- json字段为null时输出空字符串
Map < String , Object > jsonMap = new HashMap< String , Object>(); jsonMap.put(); jsonMa ...
- java-selenium上传
一.sendkeys()上传 HTML源码 <td>sendkeys上传</td> <div id='pf'><input type='file' id='p ...
- SVN随笔记录(二)
二.TortoiseSVN操作 1.下载,安装,过程中需要勾选x ,目的是为了后期绑定idea 2.如果点击后出现一系列的找不到目标文件提示,重启电脑 3.重启后,绑定仓库路径 4.一般情况输入账号密 ...