阅读《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 ...
随机推荐
- JDK部分源码阅读与理解
本文为博主原创,允许转载,但请声明原文地址:http://www.coselding.cn/article/2016/05/31/JDK部分源码阅读与理解/ 不喜欢重复造轮子,不喜欢贴各种东西.JDK ...
- 【POJ 2559】 Largest Rectangle in a Histogram
[题目链接] http://poj.org/problem?id=2559 [算法] 单调栈 [代码] #include <algorithm> #include <bitset&g ...
- IDEA 中Spark SQL通过JDBC连接mysql数据库
一.IDEA装驱动: 1.下载一个MySQL的JDBC驱动:mysql-connector-java-5.1.44.tar.gz2.在idea Open Moudle Settings 在 Moudl ...
- ie8 js编译器对象为空或不是对象的一个小问题
昨天在遍历json串的时候碰到了如下图所示的问题,除ie8以下版本的浏览器运行都是正常的, 部分代码如下: 1 var Workmodel=function(){ 2 model_json=[ 3 { ...
- Codeforces 903G 巧妙的线段树
思路: 巧妙的线段树 想方法将网络流往数据结构方向转化 http://www.cnblogs.com/yyf0309/p/8724558.html //By SiriusRen #include &l ...
- Codeforces Round #419
A Karen and Morning 找最近的回文时间 模拟 往后推 判判就行 //By SiriusRen #include <bits/stdc++.h> using namesp ...
- IOS开发 键盘添加工具条 退出 上一项 下一项 简单实现
首先设置每个 UITextField 的 inputAccessoryView 为UIToolBar : 将所有的 textField 放入一个数组: 设置 UITextField UITextFie ...
- SVN系列学习(四)-TortoiseSVN其他操作
1.新建分支 第一步:从SVN上CheckOut一份,要作为分支模板的文件 第二步:右击[TortoiseSVN]-选择[Branch/tag] 备注说明,[指明分支路径] 第三步:删除电脑上的ZJH ...
- 12.Nodes
Nodes(节点) Animation(动画) KeyframeAnimation 逐帧动画,该节点中包含了所有绑定属性的动画逻辑 Animation Group 逐帧动画分组 S ...
- 淘宝ip地址库接口会导致TTFB时间变长,网站打开速度变慢
前一段时间闲来无事发现别人的网站上有显示当前用户城市的功能,就自己也整了一个 这是淘宝ip地址库调用方法 然后问题就出现了,网站打开速度慢的要死 用F12发现是TTFB太慢,然后百度了,发现了问题的原 ...