【JavaScript】 JS面向对象的模式与实践 (重点整治原型这个熊孩子 (/= _ =)/~┴┴ )
参考书籍
JS创建对象
一.构造函数模式创建对象
/**
* description: 构造函数模式创建对象
*/
function Type (p) {
this.param = p; // 定义属性
this.method = function () { // 定义方法
return this.param;
}
}
var obj1 = new Type(1); // {param:1, method: function(){...}}
var obj2 = new Type(2); // {param:2, method: function(){...}}
console.log(obj1.method()) // 输出1
console.log(obj2.method()) // 输出2
var obj = new Object;
obj.param = p;
obj.method = function () { ... };
二.原型模式创建对象
构造函数的缺陷与加入原型的原因
var obj1 = new Type(1); // {param:1, method: function(){...}}
var obj2 = new Type(2); // {param:2, method: function(){...}}
this.method = function () { // 定义方法
return this.param;
}
构造函数和原型的关系
- 一部分是不同对象各自独有的属性, 例如上文中的param. 在需求上,我们希望不同的对象拥有不同的param
- 一部分是不同对象间共享的属性, 例如上文中的method方法,在需求上,我们希望不同的对象共同使用同一个method。
function Type (p) {
this.param = p; // 定义属性
this.method = function () { // 定义方法
return this.param;
}
}
function Type (p) {
this.param = p; // 不同对象各自独有的属性
}
Type.prototype.method = function () { // 不同对象共享的属性
return this.param;
}
原型能是个普通对象吗?(反向探究原型的工作机制)
function Type (p) {
this.param = p; // 不同对象各自独有的属性
}
Type.prototype.method = function () { // 不同对象共享的属性
return this.param;
}
// 卧槽,卧槽! 要是这么麻烦我干脆别用原型了
var obj = new Type(1);
// 超级麻烦!
console.log(Object.getPrototypeOf(obj).method.call(obj)) // 输出1
// 也很麻烦!同时这种简化破环了我们面向对象的初衷
console.log(Type.prototype.method.call(obj)) //输出1
原型的工作机制
function Type (p) {
this.param = p; // 不同对象各自独有的属性
}
Type.prototype.method = function () { // 不同对象共享的属性
return this.param;
}
var obj = new Type(1);
console.log(obj);
obj.method();
function Type () {
this.a = '实例对象中的a';
}
Type.prototype.a = 'prototype中的a';
Type.prototype.b = 'prototype中的b';
var obj = new Type();
console.log(obj); //输出 : {a: "实例对象中的a"}
console.log(obj.a); //输出:实例对象中的a
console.log(obj.b); //输出: prototype中的b
function Type () {}
Type.prototype.str = '字符串'
Type.prototype.num = 1;
Type.prototype.arr = [1,2,3];
var obj = new Type();
console.log(obj); // {}
obj.str = '覆盖后字符串';
obj.num = 2;
obj.arr = [3,4,5];
console.log(obj.str); // 覆盖后字符串
console.log(obj.num); //
console.log(obj.arr); // [3.4.5]
console.log(Type.prototype.str); // 字符串
console.log(Type.prototype.num); //
console.log(Type.prototype.arr); // [1, 2, 3]
function Type () {}
Type.prototype.str = '字符串'
Type.prototype.num = 1;
var obj = new Type();
console.log(obj); // 空实例对象 {}
obj.str +=',加点东西'; // 尝试直接修改属性
obj.num += 1; // 尝试直接修改属性
console.log(obj.str); // 字符串,加点东西
console.log(obj.num); //
console.log(Type.prototype.str); // 字符串
console.log(Type.prototype.num); // 1
console.log(obj); // {str: "字符串,加点东西", num: 2}
- 在实例中没有该属性时,直接修改基本类型的实例属性等同于为其添加属性,而且添加的属性值是在原型对象属性值的基础上进行的
- 在直接修改基本类型的实例属性时, 原型对象中的属性仍然没有变化! 这进一步证明了原型对象中的数据具有一定的“稳定性”

function Type () {}
Type.prototype.objProperty = {a: 1};
Type.prototype.arrProperty = [1,2];
var obj = new Type();
console.log(obj.objProperty) // {a: 1}
console.log(obj.arrProperty) // [1, 2]
obj.objProperty.a = 111; // 直接修改引用类型的属性值
obj.arrProperty.push(3); // 直接修改引用类型的属性值
// 原型对象中的属性值被修改了
console.log(Type.prototype.objProperty) // {a: 111}
console.log(Type.prototype.arrProperty) // [1, 2, 3]
console.log(obj); // 输出 {} obj还是空的!!
原型在OO体系中暴露的缺陷
function Type () {}
Type.prototype.arrProperty = [1,2];
var obj1 = new Type();
var obj2 = new Type();
console.log(obj2.arrProperty) // [1, 2]
obj1.arrProperty.push(3);
console.log(obj2.arrProperty); // [1, 2, 3] 我怎么被修改了???
对原型模式的评价
三.组合模式创建对象
function Person (name, age) {
this.name = name;
this.age = age;
this.friends = ['Wang','Li'];
}
Person.prototype.sayName = function () {
return this.name;
}
var person1 = new Person('Zhang',13);
var person2 = new Person('Huang',15);
person1.friends.push('Peng')
console.log(person1.friends); // ["Wang", "Li", "Peng"]
console.log(person2.friends); // ["Wang", "Li"]
console.log(person1.sayName()) // Zhang
console.log(person2.sayName()) // Huang
console.log(person1.sayName == person2.sayName) // true
JS中的继承
一.借用构造函数实现继承
/**
* description: 借用构造函数实现继承
*/
function superType () { // "父类"构造函数
this.name = "aaa";
this.sayName = function () {
return this.name
}
}
function subType () { // "子类"构造函数
superType.call(this); // 调用“父类“的构造函数
}
var obj = new subType();
console.log(obj.name); // 输出 aaa
console.log(obj.sayName()); // 输出 aaa
function superType (name) { // "父类"构造函数
this.name = name;
this.sayName = function () {
return this.name
}
}
function subType (name) { // "子类"构造函数
superType.call(this,name); // 调用“父类“的构造函数,并传递参数
}
var obj = new subType("XXX")
console.log(obj.name); // 输出XXX
console.log(obj.sayName()); // 输出XXX
二.利用原型和原型链实现继承
/**
* description: 利用原型和原型链实现继承
*/
function superType () { // "父类"构造函数
this.name = 'XXX'
}
superType.prototype.sayName = function () {
return this.name;
}
function subType () { } // "子类"构造函数
// 创建父类构造函数的实例,并赋给子类的原型
subType.prototype = new superType();
var obj = new subType();
console.log(obj.sayName()); // 输出 XXX
subType.prototype = new superType(); // {name: "XXX"}
subType.prototype = new superType();// #1
var obj = new subType(); // #2
原型链下属性的搜索机制
仅仅使用原型链实现继承的缺点
function superType () { // "父类"构造函数
this.arr = [1,2]
}
function subType () { } // "子类"构造函数
subType.prototype = new superType();
var obj1 = new subType();
var obj2 = new subType();
console.log(obj2.arr); // 输出 [1, 2]
obj1.arr.push(3);
console.log(obj2.arr); // 输出 [1, 2, 3] 卧槽,我又被乱改了!
三.组合继承
/**
* description: 组合继承的例子
*/
function SuperType (name) {
this.name = name;
this.colors = ['red','blue','green'];
}
SuperType.prototype.sayName = function () {
console.log(this.name)
}
function SubType(name, age) {
SuperType.call(this,name); // 继承实例属性
this.age = age;
}
SubType.prototype = new SuperType(); // 继承方法
SubType.prototype.sayAge = function () { // 写入新的方法
console.log(this.age)
}
var obj1 = new SubType('Wang', 20);
obj1.colors.push('black');
console.log(obj1.colors); // ["red", "blue", "green", "black"]
obj1.sayName(); // Wang
obj1.sayAge(); //
var obj2 = new SubType('Zhang', 23);
console.log(obj2.colors); // ["red", "blue", "green"]
obj2.sayName(); // Zhang
obj2.sayAge(); //
面向对象中的原型——OO体系和OLOO体系的碰撞和融合
OO设计模式
class Vehicle {
setColor (color) { this.color = color }
setWheels (num) { this.wheels = num }
setEngine (num) { this.engine = num }
}
class Car extends Vehicle { // 继承
setWheels () { this.wheels = 4 } // 方法重写
setEngine (1) { this.engine = 1 } // 方法重写
}
如图

OLOO设计模式
// 工具对象
VehicleParts = {
setWheels: function (num) { ... } // 安装车轮
setEngine: function (num) { ... } // 安装引擎
}
// 衍生对象
Car.protoType = VehicleParts; // 委托
Car.build = function () {
setWheels(4); // 4轮子
setEngine(1); // 1引擎
}
Bike.protoType = VehicleParts; // 委托
Bike.build = function () {
setWheels(2); // 2轮子
setEngine(0); // 0引擎
}
如图

对原型恰当的认知方式

【JavaScript】 JS面向对象的模式与实践 (重点整治原型这个熊孩子 (/= _ =)/~┴┴ )的更多相关文章
- JavaScript (JS) 面向对象编程 浅析 (含对象、函数原型链、闭包解析)
1. 构造函数原型对象:prototype ① 构造函数独立创建对象,消耗性能 function Person(name) { this.name = name; this.sayHello = fu ...
- JavaScript---正则使用,日期Date的使用,Math的使用,JS面向对象(工厂模式,元模型创建对象,Object添加方法)
JavaScript---正则使用,日期Date的使用,Math的使用,JS面向对象(工厂模式,元模型创建对象,Object添加方法) 一丶正则的用法 创建正则对象: 方式一: var reg=new ...
- javascript类式继承模式#3——借用和设置原型
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- javascript(js)创建对象的模式与继承的几种方式
1.js创建对象的几种方式 工厂模式 为什么会产生工厂模式,原因是使用同一个接口创建很多对象,会产生大量的重复代码,为了解决这个问题,产生了工厂模式. function createPerson(na ...
- 读《深入PHP 面向对象、模式与实践》笔记
1. include() 和require() 语句的不同在于它们如何处理错误.使用require()调用文件发生错误时,将会停止整个程序;调用include()时遇到相同的错误,则会生成警告并停止执 ...
- 读《深入php面向对象、模式与实践》有感(三)
命令模式: 第一次接触到这个命令模式的时候,感觉它很像一个简化的mvc框架.从不同的路径访问,再由控制器来判断所要调用的具体php文件. <?php class CommandContext{ ...
- 读《深入php面向对象、模式与实践》有感(二)
书中关于设计模式的介绍很详细. 一.单例模式 作者建了一个preferences类来解释什么是单例模式.这个preferences类并非我第一次见到,在android中也有这个类,不过以前都是只管用即 ...
- 《深入PHP:面向对象、模式与实践》(二)
第4章 高级特性 本章内容提要: 静态属性和方法:通过类而不是对象来访问数据和功能 抽象类和接口:设计和实现分离 错误处理:异常 Final类和方法:限制继承 拦截器方法:自动委托 析构方法:对象销毁 ...
- 《深入PHP:面向对象、模式与实践》(一)
第1章 PHP:设计与管理 本章主要介绍了本书有哪些内容. 第2章 PHP与对象 本章总结了PHP面向对象特性的发展过程,逐步介绍对象的概念. PHP/FI:支持变量.关联数组和函数.没有对象. ...
随机推荐
- 检测应用的内存泄漏情况(shell)
写代码--调试--修BUG 改来改去可能还存在一些没发现的问题,在工程量大的时候更容易出现,例如内存泄漏这样的问题,严重影响着系统性能. 网上有些检测C程序是否存在内存泄漏的工具还不错的,例如valg ...
- ListView中点击Item没有任何响应
不多说,上代码:如下图 红色方框的东西, android:descendantFocusability=”blocksDescendants” 如果不添加的话,在android的8.0手机上点击没有响 ...
- Kaggle实战之二分类问题
0. 前言 1. MNIST 数据集 2. 二分类器 3. 效果评测 4. 多分类器与误差分析 5. Kaggle 实战 0. 前言 "尽管新技术新算法层出不穷,但是掌握好基础算法就能解决手 ...
- 件测试博客日记Day03-11.17日 —— 赵天宇 —— 禅道的使用和配置详细版
说在维基百科先查找关于禅道相关知识,发现有关于禅道这个项目管理软件的详细介绍,然后将相关的介绍进行整理写入文档,在禅道的介绍中也有下载地址并进行安装. (1)软件的基本情况 a.中文名称:禅道项目管理 ...
- Iptables详解七层过滤
<Iptables详解七层过滤> 一.防火墙简介 防火墙其实就是一个加固主机或网络安全的一个设备或者软件而已,通过防火墙可以隔离风险区域与安全区域的连接,同时不会妨碍风险区域的访问.当然需 ...
- [动态规划]P1854 花店橱窗布置
题目描述 某花店现有F束花,每一束花的品种都不一样,同时至少有同样数量的花瓶,被按顺序摆成一行,花瓶的位置是固定的,从左到右按1到V顺序编号,V是花瓶的数目.花束可以移动,并且每束花用1到F的整数标识 ...
- openface 训练数据集
训练深度网络模型OpenFace还不是运用faceNet的model作为训练模型,所以在准确性上比faceNet要低,如果你只是做一个简单的分类,建议你看看官网的demo3(http://cmusat ...
- 初学PHP心得(第一天)
我是PHP初学者,听说女生挺适合学这门语言的.所以,我就下定决心,来好好的探究下它,希望它能成为我开启IT道路的第一道关卡. 今天心血来潮,来记录下一天的成果和收获吧.既然想法有了,那就要去实现它.于 ...
- Ipad弹出UIAlertControllerStyleActionSheet时发生崩溃
pad弹出UIAlertControllerStyleActionSheet时,在iphone上运行正常,但在ipad上崩溃,解决代码如下: UIAlertController *alertVc = ...
- 永中DCS再添喜讯:顺利签约海信集团
近日,永中DCS与海信集团一起携手,共创文档在线预览新篇章.出于对永中DCS文档在线预览产品的品质与服务的信赖,海信集团选择永中DCS为其提供文档在线预览技术支持,助力移动化办公(EHR系统)发展,提 ...