第六章 面向对象的程序设计

1、创建对象的几种方式

A)工厂模式

function CreatObj(name,sex,age){

this.name=name;

this.sex=sex;

this.age=age;

}

缺点:虽然可以批量创建对象,却不能知道对象的类型 只知道他是Object类型;

B)构造函数

function Person(name,sex){

this.name=name;

this.sex=sex;

this.sayName=function(){

alert(this.name);

}

}

function
Person(name,sex){

this.name=name;

this.sex=sex;

this.sayName=sayName;

}

function
sayName(){

alert(this.name);

}

优点:每个实例都有自己的实例属性,并且共享同一个方法

缺点:第一种方式函数没有复用,第二种方法是在全局作用域中的,如果方法过多对象就毫无封装性可言了

C)原型模型

function Person(){};

Person.prototype={

constructor:PerSon,

name:”hanyakui”,

age:26,

friends:[“bushi”,”jack”,”lusy”]

}

优点:解决了对象的方法复用问题

缺点:所有实例共享同一原型属性,不同实例都可以修改同一个引用类型的属性 如friends;

所有实例的属性都是一样的,都叫hanyakui 26岁

D) 组合使用构造函数和原型模型

function
Person(name,sex,friends){

this.name=name;

this.sex=sex;

this.friends=friends;

}

Person.prototype={

constructor:Person,

country:"china",

sayName:function (){

alert(this.name);

}

}

var person1 = new
Person("hanyakui", "男", ["tom",
"jack"]);

var person2 = new
Person("hanyakui222", "男22", ["2222",
"22222"]);

person2.friends.push("newadd");

优点:每个实例都有自己的实例属性(包括引用类型),同时又共享原型中的属性和方法;

这是使用最多的创建自定义类型(对象)的方式。

2、原型链

原型链的基本思想:让一个引用类型继承另一个引用类型的属性和方法,及让一个引用类型的原型(prototype)指向另一个引用类型的构造函数。

3、如何实现自定义引用类型的继承

 

A)利用原型链实现继承

//父类

function Person(){

this.name=”hanyakui”;

this.friend=["tom",
"jack"];

};

Person.prototye.sayName=function(){

alert(this.name);

}

// 子类

function ChinaPerson(){};

ChinaPerson.prototype=new
Person();

var instance1=new ChinaPerson();

alert(instance2.friends);// tom,jack

var instance2=new ChinaPerson();

instance2.friends.push(“newadd_friend”);

alert(instance2.friends);//
tom,jack,newadd_friend

alert(instance1.friends);//
tom,jack,newadd_friend

缺点:所有子类的实例都用于共同的属性和方法,尤其是引用类型属性会被所有实例共享,一个实例修改 别的实例属性就会发生变化,如上面friends

B)利用构造函数实现继承(经典继承)

function Person(name,friends){

this.name=name;

this.friends=friends;

this.sex=”男”;

 this.sayName=function(){
alert(this.name)};

}

function ChinaPerson(){

Person.apply(this,arguments)

}

var instance1=new
ChinaPerson("hanyakui",["tom","jack"]);

var instance2=new
ChinaPerson("hanyakui22",["tom22","jack22"]);

优点:继承了父类属性,同时传递了参数,从而保证子类每个实例有不同的实例属性

缺点:和使用构造函数声明对象一样 方法没复用或没有封装性

C)组合使用构造函数和原型实现继承(伪经典继承

思路:利用原型链实现对原型属性和方法的继承,利用构造函数实现实例属性的继承。

//父类

function Person(name ,friends){

this.name=name;

this.friends=friends;

}

Person.prototype.sayName=function(){

alert(this.name);

}

//子类

function ChinaPerson(){

this.country=”中国”;

Person.apply(this,arguments);    //继承实例属性

}

ChinaPerson.prototype=new Person(); //继承原型属性和方法

ChinaPerson.prototype.constructor=ChinaPerson;

ChinaPerson.prototype.sayFreinds=function(){

alert(this.freinds);

}

tip:这是最常用的继承方式、不要在父类原型中使用引用类型属性,因为所以子类实例都可以修改。

D)其他继承方式  原型式继承、寄生式继承、寄生组合式继承

第七章
函数表达式 闭包的实现

1、函数表达式

var doSomething=function(){

//do Something

};

2、闭包 (在函数内部使用匿名函数 就会构成闭包)

var objectArr=[{age:200,name=”张三”},{age:100,name:”李四”}];

function compareobject(age){

return function(obj1,obj2){

var age1=obj1.age;

var age2=obj2.age;

if(age 1< age 2) return -1;

else if(age 1> age 2) return 1;

else return 0;

};  //返回一个 闭包 ,闭包引用age;

}

objectArr.sort(compareobject(“age”));

3、变量对象 和 作用域链 (理解闭包很重要)

每个函数都有自己的执行环境,每个执行环境中都有一个表示变量的对象----变量对象作用域链本质上是一个指向 变量对象 的一个指针列表,它只引用但不实际包含变量对象。

4、闭包与变量

function
createFunction_1() {

var results = new Array();

for (var i = 0; i < 10; i++) {

results[i] = function () {return i;};

}

return results;

}

var arr = createFunction_1();

alert(arr[0]());//10

results;//[ function () {return i;},…….]

function
createFunction_2(){

var result=new Array();

for (var i=0;i<100;i++){

result[i]=function (num){

return function(){return num; }

}(i);

}

return result;

}

result;//[ function (num) { },…….]

createFunction_1:
函数内部的匿名函数构成了闭包,闭包的作用域链包含包含函数createFunction_1的变量对象i的引用,故函数执行完毕后,result的值都是100;

createFunction_2: 在闭包之外套接了一个带参数的匿名函数,由于函数参数数按照值传递的,故闭包获得的不是i的引用,而是num的值。

//疑惑

改动createFunction_1():利用了块级作用域

results[i] = (function () { return i; })();

//result值为 [0,1,2,3….9]

改动createFunction_2():

result[i] = (function (num) {return
function () { return num; }}(i))();

5、模仿块级作用域

(function(){

//这里是一个块级作用域 也称私有作用域,外围无法直接访问其中的变量(可通过特权方法访问)

})();   //(
... )
();

块级作用域:通过定义并立即调用一个匿名函数,实现块级作用域。 将函数声明包含在一对圆括号内,表示他实际上是一个函数表达式。而紧随其后的一对圆括号表示立即执行这个函数表达式。

(function createFunction_2()
{

alert("将函数声明转为函数表达式,并立即调用!");

})();

//将函数声明转为函数表达式,并立即调用!

给一个函数声明套上()函数声明就变成了函数表达式。改动createFunction_1()中将匿名函数声明改为了函数表达式并立即调用了该函数,匿名函数立即执行了,因此返回了正确的值。

6、私有变量(构造函数)

function MyObject(){

//私有变量和私有函数

var privateVariable=10;//是变量不是属性 Name:100

function privateFunction(){

return false;

}

//定义特权方法
公开私有变量和私有函数

this.publicMethod=function(){

privateVariable++;

return privateFunction();

}

}

缺点:在构造函数中定义特权方法。每个实例都换创建同样的一组方法 老毛病了 见前面

7、静态私有变量(原型)

(function(){

//私有变量和私有函数

var privateVariable=10;//是变量不是属性 Name:100

function privateFunction(){

return false;

}

// 构造函数
不使用var 关键字 声明的是全局变量

MyObject=function(){

//这是一个全局变量

};

//特权方法

MyObject.prototype.publicMethod=function(){

privateVariable++;

return privateFunction();

};

})();

优点&缺点: 私有变量和函数是所有实例共享的。

JavaScript 随笔2 面向对象 原型链 继承的更多相关文章

  1. 一步步学习javascript基础篇(5):面向对象设计之对象继承(原型链继承)

    上一篇介绍了对象创建的几种基本方式,今天我们看分析下对象的继承. 一.原型链继承 1.通过设置prototype指向“父类”的实例来实现继承. function Obj1() { this.name1 ...

  2. javascript中继承(一)-----原型链继承的个人理解

    [寒暄]好久没有更新博客了,说来话长,因为我下定决心要从一个后台程序员转为Front End,其间走过了一段漫长而艰辛的时光,今天跟大家分享下自己对javascript中原型链继承的理解. 总的说来, ...

  3. javascript原型链继承

    一.关于javascript原型的基本概念: prototype属性:每个函数都一个prototype属性,这个属性指向函数的原型对象.原型对象主要用于共享实例中所包含的的属性和方法. constru ...

  4. Javascript 组合继承 原型链继承 寄生继承

    Javascript继承通常有三种方式. 第一种:组合式继承: function SuperType(name) { this.name = name; this.colors = ["re ...

  5. 三张图搞懂JavaScript的原型对象与原型链 / js继承,各种继承的优缺点(原型链继承,组合继承,寄生组合继承)

    摘自:https://www.cnblogs.com/shuiyi/p/5305435.html 对于新人来说,JavaScript的原型是一个很让人头疼的事情,一来prototype容易与__pro ...

  6. 8条规则图解JavaScript原型链继承原理

    原形链是JS难点之一,而且很多书都喜欢用一大堆的文字解释给你听什么什么是原型链,就算有图配上讲解,有的图也是点到为止,很难让人不产生疑惑. 我们先来看一段程序,友情提示sublimeText看更爽: ...

  7. JavaScript之原型链与原型链继承

    原型链 定义:每个实例对象(object)都有一个私有属性(称之为 __proto__ )指向它的构造函数的原型对象(prototype).该原型对象也有一个自己的原型对象(__proto__),层层 ...

  8. Javascript 对象继承 原型链继承 对象冒充 call 混合方式

    一.原型链继承 function ClassA() {} ClassA.prototype.color = "blue"; ClassA.prototype.sayColor = ...

  9. js原型链继承的傻瓜式详解

    本文争取用最简单的语言来讲解原型链继承的OOP原理 0.如果对原型继承还没有大致了解,完全一头雾水,请先阅读 <JavaScript高级程序设计>第六章最后部分的寄生组合式继承 或者_廖雪 ...

随机推荐

  1. 使用delphi+intraweb进行微信开发1--微信平台接入

    示例代码已经放出!请移步使用delphi+intraweb进行微信开发1~4代码示例进行下载,虽为示例代码但是是从我项目中移出来的,封装很完备适于自行扩展和修改. iw14.0.50来了,在新的版本中 ...

  2. Oracle分区表!

    Oracle 数据库分区表的创建和操作 摘要:在大量业务数据处理的项目中,可以考虑使用分区表来提高应用系统的性能并方便数据管理,本文详细介绍了分区表的使用. 在大型的企业应用或企业级的数据库应用中,要 ...

  3. Zip文件压缩(加密||非加密||压缩指定目录||压缩目录下的单个文件||根据路径压缩||根据流压缩)

    1.写入Excel,并加密压缩.不保存文件 String dcxh = String.format("%03d", keyValue); String folderFileName ...

  4. Delphi DateUtils时间单元

    Uses DateUtils //时间单元,非常有用. 记得引用这个单元,不然不能用. CompareDate 比较两个日期时间值日期部分的大小 CompareDateTime 比较两个日期时间值的大 ...

  5. 关于处理小数点位数的几个oracle函数

    1. 取四舍五入的几位小数 select round(1.2345, 3) from dual; 结果:1.235 2. 保留两位小数,只舍 select trunc(1.2345, 2) from ...

  6. angularjs中文社区

    http://angularjs.cn/   中文社区 https://angular.cn/features.html  官方文档中文版

  7. 你是否经常忘记网站上的各种密码?分享个密码管理软件LastPass

      现在网络那么发达,我们上网的每个人势必会在各个网站上登陆,那势必会有一堆密码需要管理,那怎么能记住那么多网站的密码呢?我之前的做法是设置几个常用的密码,好多不重要的网站用一个,重要的网站用一个,然 ...

  8. JS操作JSON总结

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是 JavaScript 原生格式,这意 ...

  9. 解决CentOS无法解析域名的问题

    用SecureCRT连接到CentOS上,发现ping IP通,ping地址不同 [root@zyt-ceshi2 ~]# ping www.baidu.comping: unknown host w ...

  10. 用EXCEL内嵌的Visual Basic for Application 编程,通过 UGSimple USB-GPIB 控制器来驱动仪器34401A,并从34401A读取数据

    现在市场上有很多中USB-GPIB 控制器,或叫 USB 转GPIB链接线. 每种GPIB控制器都有它的 函数库(dll库).各种GPIB 控制器的价钱插别很大.这里以一种价钱较便宜的USB-GPIB ...