阅读《JavaScript设计模式》第二章心得
面向对象编程
面向对象编程就是将你的需求抽象成一个对象。然后针对这个对象分析其特征(属性)与动作(方法)。这个对象我们称之为类。面向对象编程思想其中的一个特点就是封装。
1、私有属性、私有方法、特权方法、对象公有属性、对象公有方法、构造器和类静态公有属性、类静态公有方法、公有属性、公有方法
var Book = function (id,name,price){
//私有属性
var num = 1;
//私有方法
function checkId(){};
//特权方法
this.getName = function(){};
this.getPrice = function(){};
this.setName = function(){};
this.setPrice = function(){};
//对象公有属性
this.id=id;
//对象公有方法
this.copy=function(){};
//构造器
this.setName(name);
this.setPrice(price);
};
//类静态公有属性(对象不能访问)
Book.isChinese = true;
//类静态公有方法(对象不能访问)
Book.resetTime = function(){
console.log('new Tiem')
};
Book.prototype = {
//公有属性
isJSBook : false;
display : function(){}
}
测试代码如下
var b = new Book(11,22,33);
console.log(b.num); //undefined
console.log(b.isJSBook); //false
console.log(b.id); //
console.log(b.isChinese); //undefined
console.log(Book.isChinese); //true
Book.resetTime(); //new Tiem
2、闭包实现
闭包是有权访问另一个函数作用域中变量的函数,即在一个函数中创建另一个函数。
new关键字的作用可以看作是对当前对象的this不停的赋值。如果实例化的时候不写new就相当于在全局作用域中执行了实例化函数,那么实例化就会出现问题
由于小程序中没有window对象,所以在全局实例化不带new时候就会报错,但是网页中就不会报错。
解决忘记写new的方法是使用安全模式,代码如下:
var Book = function (title, time, type){
//判断执行过程中this是否是当前这个对象(如果是说明是用new创建的)
// 判断 foo 是否是 Foo 类的实例 //function Foo(){} //var foo = new Foo(); //console.log(foo instanceof Foo)//trueif(this instanceof Book){ //这里的instance是指this指向的对象是否是Book的实例,而不是指this是否指向Book
this.title = title;
this.time = time;
this.type = type;
}else{
return new Book(title,time,type);
}
}
3、继承
new之后的变量是没有prototype的 ,只有__proto__属性,也就是实例化之后就没有prototype原型了,但是prototype是等于实例化之后的__proto__的。实例化之后的变量的__proto__中的constructor是等于实例化之前的构造函数的。
但是在打印实例化之后的构造函数时可以这样:
console.log(a.__proto__.constructor)
也可以这样
console.log(a.constructor)
打印出来的都是实例化之前的构造函数,因为如果查找一个属性在变量中找不到就会去变量的隐藏属性__proto__中去找。
查找是没有什么 区别,但是添加方法的作用域不同
如果写a.__proto__.b,那么这个b方法将在__proto__中执行,this指向的是a.__proto__的作用域
如果写a.b,那么这个b方法将在a中执行,this指向的是a的作用域
JavaScript中除了数字、字符串、布尔值、null和undefined之外的就是对象了,所以数组是对象,对象之间相互赋值只是更换的内存地址,内存地址所指向的值都是一样的,是会相互影响的。
详情请戳这 JavaScript中值类型和引用类型的区别
下面放寄生组合式继承实例:
function inheritObject(o){
function F(){}
F.prototype = o;
return new F();
}
function inheritPrototype(subClass,superClass){
var p = inheritObject(superClass.prototype);
console.log(p)
console.log(superClass)
p.constructor = subClass;
subClass.prototype = p
}
function SuperClass(name){
this.name = name;
this.colors = ["red","blue","green"];
}
SuperClass.prototype.getName = function(){
console.log(this.name)
}
function SubClass(name,time){
SuperClass.call(this,name)
this.time = time;
}
inheritPrototype(SubClass,SuperClass);
SubClass.prototype.getTime = function(){
console.log(this.time)
}
var instance1 = new SubClass("js book",2014)
var instance2 = new SubClass("css book",2013)
instance1.colors.push("black")
console.log(instance1.colors)
console.log(instance2.colors)
instance2.getName();
instance2.getTime();
4、多继承
for in 用法可以遍历一个对象中的属性或者方法,可以像遍历数组一样简单。
arguments可以用来遍历那些传参数量不确定的函数,不用写形参就可以获取到实参的值和数量。该对象还封装了callee方法,该方法可用来实现递归。
Object.prototype.mix = function () {
var i = 0,
len = arguments.length
var arg;
for (; i < len; i++) {
arg = arguments[i];
for (var p in arg) {
this[p] = arg[p]
}
}
}
var book1 = {
name: "javascript设计模式",
alike: ['css', 'html', "javascript"]
}
var book2 = {
color: "blue"
}
var otherBook1 = {
aa: "11"
}
var otherBook2 = {
bb:"22"
}
otherBook1.mix(book1, book2)
otherBook1.alike.push("ajax")
console.log(otherBook1)
otherBook2.mix(book1, book2)
console.log(otherBook2)
这里可以看到引用类型属性还是共用的。
浅复制中的复制对象的方法对象实质是一种指向引用,所以我们在深复制中要把该对象中的引用类型属性细化成值类型拷贝到目标对象中。
这是本章最后的一个问题,如何实现深复制。
然后我又回头看看之前写的单继承怎么实现的引用类型属性不共用的(之前还真的没有仔细看过如何引用类型属性不共用的),然后发现原来在构造函数继承的地方就已经实现了应用类型属性不共用的方法。
使用call改变函数作用的环境就可以实现。(这让我想到之前每次调用别的函数时都使用call,现在才知道call改变函数作用环境的目的不仅仅是改变this的指向,也可以实现应用类型属性不共用,从而达到真正复制该方法的作用)
但是这里并没有用到构造函数的方法。
Object.prototype.mix = function () {
var i = 0,
len = arguments.length
var arg;
for (; i < len; i++) {
arg = arguments[i];
for (var p in arg) {
if (typeof arg[p] == 'object') {
var str = JSON.stringify(arg[p])
this[p] = JSON.parse(str);
} else {
this[p] = arg[p]
}
console.log(typeof arg[p])
}
}
}
var book1 = {
name: "javascript设计模式",
alike: ['css', 'html', "javascript"]
}
var book2 = {
color: "blue"
}
var otherBook1 = {
aa: "11"
}
var otherBook2 = {
bb: "22"
}
otherBook1.mix(book1, book2)
otherBook1.alike.push("ajax")
console.log(otherBook1)
otherBook2.mix(book1, book2)
console.log(otherBook2)
这样就实现了多继承的深复制
5、多态
这里的多态就是同一种方法多中调用方式,实质就是上面arguments的用法,根据传参的数量不同而调用的方法不同。
本人处于学习阶段,如有误欢迎大家的指出。
阅读《JavaScript设计模式》第二章心得的更多相关文章
- [head first 设计模式]第二章 观察者模式
[head first 设计模式]第二章 观察者模式 假如我们有一个开发需求--建造一个气象观测站展示系统.需求方给我们提供了一个WeatherObject对象,能够自动获得最新的测量数据.而我们要建 ...
- javascript设计模式 第一章 灵活的javascript
javascript 设计模式 第1章 灵活的语言--JavaScript 初级程序员接到一个验证表单功能的任务,需要验证用户名.邮箱.密码等 ** 此文章内容大部分来自 <javascript ...
- 《JavaScript高级程序设计(第3版)》阅读总结记录第二章之在HTML中使用JavaScript
本章目录: 2.1 <script> 元素 2.1.1 标签的位置 2.1.2 延迟脚本 2.1.3 异步脚本 2.1.4 在XHTML 中的用法 2.1.5 不推荐使用的语法 2.2 嵌 ...
- 读高性能JavaScript编程 第二章 让我知道了代码为什么要这样写
代码为什么要这样写? function initUI(){ var doc = document, bd = doc.body, links = doc.getElementsByTagName_r( ...
- Effective JavaScript :第二章
1.熟练掌握闭包 理解闭包要学会三个基本的事实: ①JavaScript允许你引用在当前函数以外定义的变量: 例如: function makeSandwich(){ var magicIngredi ...
- Android深度探索-卷1第二章心得体会
这章介绍了搭建Android开发环境的的搭建,主要是在Linux上搭建Android开发环境总体来说因为都是在Linux下开发的,so,只介绍了在Linux环境下的搭建在搭建过程中全是命令操作,和Wi ...
- Javascript设计模式笔记
Javascript是越来越厉害了,一统前后端开发.于是最近把设计模式又看了一遍,顺便做了个笔记,以方便自己和他人共同学习. 笔记连载详见:http://www.meteorcn.net/wordpr ...
- JavaScript设计模式(一)
使用JavaScript框架和库过程中, 我遇到过很多感觉上'奇形怪状'的代码. 大多数情况下, 按照惯例编写代码也能够写出很多出色的功能. 但是如果不从根本上理解它们实现的方法, 就没办法完全充分发 ...
- [书籍翻译] 《JavaScript并发编程》 第二章 JavaScript运行模型
本文是我翻译<JavaScript Concurrency>书籍的第二章 JavaScript运行模型,该书主要以Promises.Generator.Web workers等技术来讲解J ...
随机推荐
- cocos2D(七)---- CCScene
CCScene普通情况是游戏里面的根节点.称之为"场景",执行游戏时须要通过CCDirector启动第一个场景. 当然,游戏略微复杂一点的话.可能会包括非常多个场景,这就涉及到场景 ...
- willRotateToInterfaceOrientation 屏幕旋转
/* 1.屏幕发生旋转后, 这个旋转事件会先传递给window的rootViewController(窗口的根控制器) 2.rootViewController又会将这个旋转事件传递给它的子控制器 * ...
- Java课程设计——人事管理系统
主界面代码: package PersonSystem; import java.awt.*; import java.awt.event.*; import javax.swing.*; impor ...
- 技术的止境(客户价值第一,快速实现第二,边做边学,迅速成为牛人。紧贴客户的需求去做技术,立于不败之地。追求的目标:把一项产品去做好,用产品去养活自己和家人)good
作为一个依靠技术来谋生的程序员,我最近一直在思考一个问题,有限的生命里,面对无限的技术更新,我要研究到什么程度才能算是完成我的成为技术大牛的目标呢?换而言之,那就是技术的止境在哪儿呢?深入的思考下去, ...
- canvas上的像素操作(图像复制,细调)
canvas上的像素操作(图像复制,细调) 总结 1.操作对象:ImageData 对象,其实是canvas的像素点集合 2.主要操作: var obj=ctx.getImageData(0,0,10 ...
- bzoj1098
并查集+dfs 先开始想和不相连的点用并查集连起来,最后看每个连通块有多少个点就行了,但是这样是O(n*n)的,然而我并没有想到补图 其实就是求补图有多少连通块,因为补图中两个点有边,那么这两个点必须 ...
- bzoj3545
线段树合并+离线+启发式合并 半年前这道题t成狗... 离线的做法比较好想,按照边的权值排序,询问的权值排序,然后枚举询问不断加边,加到上限后查找第k大值,这里平衡树,权值线段树都可以实现. 那么我们 ...
- VPS主机
腾讯云企业认证 备案域名要是顶级域名格式,所以不能是www.blueheartzf.com,而要是blueheartzf.com
- ckeditor详细设置
CKEditor 3 JavaScript API Documentation : http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.con ...
- web安全:防止浏览器记住或自动填写用户名和密码(表单)的终极解决方案
最近项目上要求做到这一点,在网上搜了一圈,发现都是不完美的,不兼容全部的浏览器,于是只能自己摸索了,最终得出了终极解决方案: 涉及: disabled 或 readonly display:none; ...