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

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. [LeetCode OJ] Max Points on a Line

    Max Points on a Line Submission Details 27 / 27 test cases passed. Status: Accepted Runtime: 472 ms ...

  2. Magic xpa 2.5发布 Magic xpa 2.5 Release Notes

    Magic xpa 2.5發佈 Magic xpa 2.5 Release Notes Magic xpa 2.5 Release NotesNew Features, Feature Enhance ...

  3. 庆祝下:iOS 开发者企业级计划(299美元/年帐户+邓白氏码免费) 和 Windows Phone公司应用(公司帐户99美元+Symantec企业证书299美元/年))顺利发布成功

    时间:2013-11-15,地址:http://192.168.0.8  网站可下载三个终端应用直接安装IOS,Windows Phone,Android iOS: 企业版IDP通过 iTunes.使 ...

  4. EX的魔方

    https://www.luogu.org/problem/show?pid=2007 题目背景 常神牛从来没接触过魔方,所以他要借助计算机来玩.即使是这样,他还是很菜. 题目描述 常神牛家的魔方都是 ...

  5. Python之RabbitMQ操作

    RabbitMQ是一个消息代理,从“生产者”接收消息并传递消息至“消费者”,期间可根据规则路由.缓存.持久化消息.“生产者”也即message发送者以下简称P,相对应的“消费者”乃message接收者 ...

  6. 图片转base64

    function convertImgToBase64(url, callback, outputFormat){ var canvas = document.createElement('CANVA ...

  7. 安装spf13-vim on Windows10

    安装之前 1.系统为 windows10  Version 1607 64位 企业版 2.参考 http://www.codeweblog.com/gvim-64%E4%BD%8D-windows-7 ...

  8. js中js数组、对象与json之间的转换

    在数据传输过程中,json是以文本,即字符串的形式传递的,而JS操作的是JSON对象,所以,JSON对象和JSON字符串之间的相互转换是关键.例如:JSON字符串:var str1 = '{ &quo ...

  9. IIS7 IIS8 中多个版本php共存的方法

    原文地址: https://blog.cozof.com/pieces/54.shtml 最近又重回.net,用回IIS.然后用到某个php开源项目,需要低版本的php,之前装的一个php5.5不能用 ...

  10. MyEclipse配置Tomcat 6

    打开首选项 禁用MyEclipse自带的Tomcat 6 下载apache-tomcat-6.0.29.tar.gz 地址:http://yunpan.cn/cKg6kq2RmjdUB  提取码 98 ...