JavaScript 随笔2 面向对象 原型链 继承
第六章 面向对象的程序设计
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 面向对象 原型链 继承的更多相关文章
- 一步步学习javascript基础篇(5):面向对象设计之对象继承(原型链继承)
上一篇介绍了对象创建的几种基本方式,今天我们看分析下对象的继承. 一.原型链继承 1.通过设置prototype指向“父类”的实例来实现继承. function Obj1() { this.name1 ...
- javascript中继承(一)-----原型链继承的个人理解
[寒暄]好久没有更新博客了,说来话长,因为我下定决心要从一个后台程序员转为Front End,其间走过了一段漫长而艰辛的时光,今天跟大家分享下自己对javascript中原型链继承的理解. 总的说来, ...
- javascript原型链继承
一.关于javascript原型的基本概念: prototype属性:每个函数都一个prototype属性,这个属性指向函数的原型对象.原型对象主要用于共享实例中所包含的的属性和方法. constru ...
- Javascript 组合继承 原型链继承 寄生继承
Javascript继承通常有三种方式. 第一种:组合式继承: function SuperType(name) { this.name = name; this.colors = ["re ...
- 三张图搞懂JavaScript的原型对象与原型链 / js继承,各种继承的优缺点(原型链继承,组合继承,寄生组合继承)
摘自:https://www.cnblogs.com/shuiyi/p/5305435.html 对于新人来说,JavaScript的原型是一个很让人头疼的事情,一来prototype容易与__pro ...
- 8条规则图解JavaScript原型链继承原理
原形链是JS难点之一,而且很多书都喜欢用一大堆的文字解释给你听什么什么是原型链,就算有图配上讲解,有的图也是点到为止,很难让人不产生疑惑. 我们先来看一段程序,友情提示sublimeText看更爽: ...
- JavaScript之原型链与原型链继承
原型链 定义:每个实例对象(object)都有一个私有属性(称之为 __proto__ )指向它的构造函数的原型对象(prototype).该原型对象也有一个自己的原型对象(__proto__),层层 ...
- Javascript 对象继承 原型链继承 对象冒充 call 混合方式
一.原型链继承 function ClassA() {} ClassA.prototype.color = "blue"; ClassA.prototype.sayColor = ...
- js原型链继承的傻瓜式详解
本文争取用最简单的语言来讲解原型链继承的OOP原理 0.如果对原型继承还没有大致了解,完全一头雾水,请先阅读 <JavaScript高级程序设计>第六章最后部分的寄生组合式继承 或者_廖雪 ...
随机推荐
- pacman -Syu : key could not be looked up remotely.
# sudo pacman -Syu...error: key "5F702428F70E0903" could not be looked up remotelyerror: r ...
- openscales实现漂亮的冒泡效果
使用的时候openscales 默认的冒泡效果确实有点简陋,想实现那种看着比较舒服的效果,只能自己定义了.参考现有的openscales实现的方式,它是通过控件的状态实现的,每个状态中使用Path绘制 ...
- ionic 里使用 iframe 可能遇到的问题
无法访问外部url的问题--两个步骤解决: iframe的src属性用ng-src属性替代,并指明绑定对象: ng-src="{{targetUrl}}" 在controller里 ...
- Java 2D API - 2. Graphics 入门
Java 2D API强大而复杂,不过大多时候我们只需使用java.awt.Graphcis类的部分功能.下面的内容将覆盖大多数的常见应用. Graphics 类中的方法大致可以分为两类: Draw ...
- ios中,在SearchBar里面搜索内容,可根据内容来查找所需的信息资源,可获得SearchBar中的内容
贴一段我很久以前写的小demo,你们就明白了,是把textField套在alertView里的@interface ViewController : UIViewController <UIAl ...
- JS-获取URL请求参数
前言:原来做过一个项目,需要实现一个页面打印的功能,由于项目中使用了AngularJS+Bootstrap等前端框架,需要打印的页面又在弹出框中,使用了Bootstrap的模态框后发现打印的效果不太好 ...
- window.onload和window.document.readystate的探究
在编写前端页面的时候,我们时常需要对页面加载的状态进行判断,以便进行相应的操作. 比如在移动端,时常需要在页面完全加载完成之前,先显示一个loading的图标,等待页面完成加载完成后,才显示出真正要展 ...
- 在MFC中使用GDI+的一般方法,以VC6.0编译器为例
1.载解压GDI+开发包: 2.正确设置include & lib 目录: 设置如下:VC6.0编译器菜单Tools->Options->Directories中添加inlude ...
- 三剑客之SED
Sed功能说明 Sed是Strem Editor(流编辑器)缩写,是操作.过滤和转换文本内容的强大工具.常用功能有增删改查,过滤,取行. [root@old ~]# sed --versio ...
- Java堆内存的十个要点
Java中的堆空间是什么? 当Java程序开始运行时,JVM会从操作系统获取一些内存.JVM使用这些内存,这些内存的一部分就是堆内存.堆内存通常在存储地址的底层,向上排列.当一个对象通过new关键字或 ...