阅读《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 ...
随机推荐
- nginx安装【windows下安装】
http://nginx.org/en/download.html 解压: 2.启动nginx 有很多种方法启动nginx (1)直接双击nginx.exe,双击后一个黑色的弹窗一闪而过[不是失败就是 ...
- 小胖说事31------iOS 真机编译错误"“XXX”的 iPod" and run "XXX" again, or if "XXX" is still running
在真机上測试时用一会就出现例如以下信息,且应用挂掉. Restore the connection to ""XXX"的 iPod" and run " ...
- Android 自己定义UI圆角button
Android实际开发中我们一般须要圆角的button,普通情况下我们能够让美工做出来对应的button图片.然后放上去就可以,另外我们能够在布局文件里直接设置,也能够达到一样的效果. 以下解说在布局 ...
- Android应用资源
Java刚開始学习的人直接在Java源代码使用"hello" 和123 类型的字符串和整型.但时间长了就会忘记当初定义的原因,有经验的或许会定义字符串常量ResultSet.TYP ...
- RatingBar android:isIndicator="true"
有时候我们用RatingBar只须要显示不让它选择或改变,解决办法是设置属性 android:isIndicator="true" isIndicator的意思是:是否是指示器,如 ...
- Bing Maps进阶系列六:使用Silverlight剪切(Clip)特性实现Bing Maps的迷你小地图
Bing Maps进阶系列六:使用Silverlight剪切(Clip)特性实现Bing Maps的迷你小地图 Bing Maps Silverlight Control虽然为我们提供了简洁.方面的开 ...
- bzoj2844
http://www.lydsy.com/JudgeOnline/problem.php?id=2844 线性基... 先把线性基搞出来,然后不断逼近答案,如果这个基比答案小了,那么说明要加上,同时加 ...
- javamail - 协议SMTP\IMAP\POP3设置
资料来自:https://www.tutorialspoint.com/javamail_api/index.htm [SMTP - Simple Mail Transfer Protocol] Na ...
- MyBatis高级查询 一对一映射
drop database if exists simple; create database simple; use simple; drop table if exists sys_user; c ...
- 设计模式 |备忘录模式(memento)
定义: 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可以将该对象恢复到原先保存的状态. 结构:(书中图,侵删) Originator:需要备份的类(写在便签上 ...