面向对象编程

面向对象编程就是将你的需求抽象成一个对象。然后针对这个对象分析其特征(属性)与动作(方法)。这个对象我们称之为类。面向对象编程思想其中的一个特点就是封装。

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)//true

  if(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、多继承

关于js中的for  in和in用法

for in 用法可以遍历一个对象中的属性或者方法,可以像遍历数组一样简单。

关于js中arguments用法

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设计模式》第二章心得的更多相关文章

  1. [head first 设计模式]第二章 观察者模式

    [head first 设计模式]第二章 观察者模式 假如我们有一个开发需求--建造一个气象观测站展示系统.需求方给我们提供了一个WeatherObject对象,能够自动获得最新的测量数据.而我们要建 ...

  2. javascript设计模式 第一章 灵活的javascript

    javascript 设计模式 第1章 灵活的语言--JavaScript 初级程序员接到一个验证表单功能的任务,需要验证用户名.邮箱.密码等 ** 此文章内容大部分来自 <javascript ...

  3. 《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 嵌 ...

  4. 读高性能JavaScript编程 第二章 让我知道了代码为什么要这样写

    代码为什么要这样写? function initUI(){ var doc = document, bd = doc.body, links = doc.getElementsByTagName_r( ...

  5. Effective JavaScript :第二章

    1.熟练掌握闭包 理解闭包要学会三个基本的事实: ①JavaScript允许你引用在当前函数以外定义的变量: 例如: function makeSandwich(){ var magicIngredi ...

  6. Android深度探索-卷1第二章心得体会

    这章介绍了搭建Android开发环境的的搭建,主要是在Linux上搭建Android开发环境总体来说因为都是在Linux下开发的,so,只介绍了在Linux环境下的搭建在搭建过程中全是命令操作,和Wi ...

  7. Javascript设计模式笔记

    Javascript是越来越厉害了,一统前后端开发.于是最近把设计模式又看了一遍,顺便做了个笔记,以方便自己和他人共同学习. 笔记连载详见:http://www.meteorcn.net/wordpr ...

  8. JavaScript设计模式(一)

    使用JavaScript框架和库过程中, 我遇到过很多感觉上'奇形怪状'的代码. 大多数情况下, 按照惯例编写代码也能够写出很多出色的功能. 但是如果不从根本上理解它们实现的方法, 就没办法完全充分发 ...

  9. [书籍翻译] 《JavaScript并发编程》 第二章 JavaScript运行模型

    本文是我翻译<JavaScript Concurrency>书籍的第二章 JavaScript运行模型,该书主要以Promises.Generator.Web workers等技术来讲解J ...

随机推荐

  1. 自然语言处理中的Attention Model:是什么及为什么

    /* 版权声明:能够随意转载.转载时请标明文章原始出处和作者信息 .*/ author: 张俊林 要是关注深度学习在自然语言处理方面的研究进展,我相信你一定听说过Attention Model(后文有 ...

  2. Localhost 回环IP 127.0.0.1

    LocalHost 127.0.0.1是一个保留地址,用于本地软件測试以及本地进程间通信, 也叫回环IP.回环地址.回送地址(loopback address).不管什么程序,一旦使 用回环IP发送数 ...

  3. c++中读写文件操作

    读写文件这个,不常用,每次用的时候都会百度一下,每次写法还都不一样,所有总是记混.今天利用点时间总结下之前工程中用过的.以后就安照这种方法写了. 搞acmicpc的时候喜欢用freopen(),这个是 ...

  4. ASP.NET 4 and Visual Studio 2010

    https://msdn.microsoft.com/en-us/library/ee532866.aspx The topics in this section provide informatio ...

  5. Android之仿今日头条顶部导航栏效果

    随着时间的推移现在的软件要求显示的内容越来越多,所以要在小的屏幕上能够更好的显示更多的内容,首先我们会想到底部菜单栏,但是有时候像今日头条新闻客户端要显示的内容太多,而且又想在主界面全部显示出来,所以 ...

  6. codeforces 949B A Leapfrog in the Array

    B. A Leapfrog in the Array time limit per test 2 seconds memory limit per test 512 megabytes input s ...

  7. [BZOJ 1660] Bad Hair Day

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1660 [算法] Sprease Table + 二分 时间复杂度 : O(NlogN ...

  8. P1491 集合位置 次短路

    这个题是一个次短路的裸题,就是把最短路路径求出来之后依次删边,然后跑最短路,在这些情况里取最小值就行了. 题干: 每次有大的活动,大家都要在一起“聚一聚”,不管是去好乐迪,还是避风塘,或者汤姆熊,大家 ...

  9. 45. ExtJS ComboBox 下拉列表详细用法

    转自:https://blog.csdn.net/luckypeng/article/details/46496151 ComboBox 是ExtJS中经常用到的控件,今天我们来讲一下它的一些用法. ...

  10. 53. 部门信息显示 EXTJS 单击树节点

    1. /** * @author sux * @time 2011-1-14 * @desc 部门信息显示 */ deptInfoGridPanel = Ext.extend(Ext.grid.Edi ...