关于面向对象的总结和疑惑(转载可乐冰

在这节,老师讲了面向对象的三大特性:1、全局变量;2、封装;3、继承;

现在我就我自己的理解总结一下这节课的内容,并提出相应的疑惑,望老师解答

其一:全局变量

声明变量的方法有三:1,在全局对象中var a一个变量;2,window.a一个变量;3.直接去掉var,如:a=1一个变量。

第一种声明方式是我们声明变量的标准形式。现在我主要说说第二种和第三种声明变量的方式:

对于第二种方式和第三种方式声明的变量,不同于标准声明1:

其实实质上就是创建了全局对象的一个新属性,本质上不是变量。并且这两种方式声明的变量只在代码执行阶段才会出现,在预解析代码时是不会出现在执行环境中(变量对象)中。

对于第二种方式和第三种方式声明的变量,不同于标准声明2:

这两种声明变量的方式是可以运用delete操作符删除的,而标准声明方式却不能,原因在于标准声明的变量有一个Donot delete属性。(也除例外情况,如:在eval上下文中,标准声明的方式没有Donot delete这个属性,所以也是可以删除的)

注:例外在声明变量时应少声明全局变量,会引发一些不必要的影响

其二:封装

说到封装,先讲讲三大声明的形式:1、private;2、protected;3、public

js中并没有这些特性,但我们可以通过代码人为实现这三种特性

对于私有类型(private),我们便可以采用封装的形式,将函数中一部分信息隐藏,但为了给外部引用,提供相应的接口(我觉得这就是引用闭包的特性,来实现这些接口)

对于保护类型(protected),虽然没有其实现方法,但我们可以通过人为的书写规范来辨别,如:将受保护类型的变量,可以在变量名前加下划线来区分它与公有类型。

其三:继承(困扰我好久)

其实,老师上课说的继承的两种实现方式,只说了其实现过程,并没有具体和我们分析分析,所以我就找了好多资料,来做一个总结吧!

先说说普通的原型链继承:

function sub(){

this.proterty=true;

}

sup.prototype.getValue=function(){

return this.property;

}

function sub(){

this.subValue=false;

}

sub.prototype=new sup();

var instance=new sub();

alert(instance.getValue());

原型链继承:

原理:

就是通过原型链来实现的继承,就是你的sub函数的原型对象的_proto_属性指向sup的原型对象,而sub实例化的instance对象的_proto_属性指向sub的原型对象,通过这条链来查找所需方法和属性。

优点:可以在sup的原型对象中添加的方法可以实现共享,利于代码的复用

缺点:如果sub中的引用类型的属性会被所有实例化的对象共享,不能保证各实例化对象的不同状态。

为了解决原型链继承这个缺点,我们引用了借用构造函数继承的方法:

function sup(){

this.num=[1,2,3];

}

function sub(){

sup.call(this);

}

var instance1=new sub();

instance1.num.push(‘4‘);

var instance2=new sub();

instanc2.num.push(‘5‘);

借用构造函数继承:

原理:

就是通过这行关键代码来实现继“sup.call(this);”,这行代码的意思就是,在sub的词法环境中我们在全局作用域中调用sup函数(借用sup的函数),所以执行完这行代码一行以后,sub就继承了sup。之后在实例化sub时,每个实例化对象,都会有num属性的副本,这其中就是通过this的指向来完成的。如:实例化instance1时,sub中的this就会指向instance1,而sub会借用sup的this,所以每个实例化的num属性都会不一样,这样就可以实现各实例化对象的不同状态。

优点:可以实现各实例化对象的不同状态;

缺点:不利于代码的复用

综合上面两种继承方法的优缺点,就引出了第三种继承方案:组合继承

function sup(name){

this.name=name;

this.num=[1,2,3]

}

sup.prototype.sayName=function(){

alert(this.name);

}

function sub(){

sup.call(this);

}

sub.prototype=new sup();

sub.prototype.construcor=sub;

var instance1=new sub();

instance1.num.push(‘4‘);

instance1.sayName();

var instance2=new sub();

instanc2.num.push(‘5‘);

instance2.sayName();

组合继承:

原理:综合以上两种方式的原理来实现;

优点:可以让sub的不同实例化对象分别有自己的状态属性,而且又可以使用相同的方法

缺点:两次调用sup构造函数,不利于性能优化

为了解决组合继承这个缺点,我们引用了寄生式组合继承的方法:

function imp(sub,sup){

var proto=Object(sup.prototype);

proto.constructor=sup;

sub.prototype=proto;

}

function sup(name){

this.name=name;

this.num=[1,2,3];

}

sup.prototype.sayName=function(){

alert(this.name);

}

function sub(){

sup.call(this);

}

imp(sub,sup);

寄生式组合继承:

原理,之前说的两次调用sup构造函数,第一次是sup.call(this);第二次是创建sub对象原型的时候;分析第二次调用sup构造函数,其实实质上就是我们需要的只是sup原型对象的一个副本,说白了就是希望sub原型对象的_proto_属性指向sup的原型对象。为了解决这个问题,我们可以用一个函数封装来实现

function imp(sub,sup){

var proto=Object(sup.prototype);

proto.constructor=sup;

sub.prototype=proto;

}

只要我们创建一个sup的原型对象,在把sup原型对象的construct指或sup,最后在把sub的原型对象指向sup的原型对象。我们就可以实现继承sup原型对象上的方法了

优点:避免在sub的原型对象上创建不必要的属性。

说完了我对高程上继承的理解,我说说老师课上继承的两种方式:1、类继承;2、原型继承

其一:类继承

(function(){

function classA(){};

classA.classMethod=function(){};

classA.prototype.api=function(){};

function classB(){

classA.apply(this,arguments);

}

classB.prototype=new classA();

classB.prototype.constructor=classB;

classB.prototype.api=function(){

classA.prototype.api.call(this,arguments);

}

var b=new classB()

})()

关于这段代码,我提出两个疑问:

疑惑一:

classB.prototype.constructor=classB;

关于这句语句:

我的理解:将classB原型对象上的constructor指回classB;

原因是执行完classB.prototype=new classA();以后classB的原型对象指向了classA的原型对象,而classA的原型对象中的constructor属性是指向classA的

我的疑惑:如果不加这句语句,那么classB原型对象上的constructor属性指向哪里?是classA吗?(我理解的constructor属性指向prototype属性所在的构造函数)如果不加这句语句,那么通过classB实例化的对象b,b的构造器会指向classA不会指向classB吗?对原形链有什么影响吗?请老师好好帮我分析分析,我实在想不出!

疑惑二:

classA.prototype.api.call(this,arguments);

关于这句语句:

我的理解:就是在classB的原型对象上添加api方法。我认为在classA的原型对象中已经添加了api方法,我们可以通过原型继承(原型链),在classB实例化的对象中访问到api方法,不需要再在classA的原型对象上在调用一次这个方法.请问老师这样写还有其他目的吗?还是我的理解不准确?

其二:原型继承

(function(){

var proto={

action1:function(){}

}

var obj=Object.create(proto);

})()

对于原型继承我的理解是:它和之前说的原型链继承有同样的弊端,不利于每个实例对象的属性状态的不同的保存。

这种继承还存在兼容性,我们可以封装一个函数解决。

以上就是我对继承的理解,因为还是学生,没有实践经历,理解层次还处于理论阶段,可以在以后实践会有不同吧!慢慢来。

在前端自学的路上,遇到好多问题,想对继承方法的命名不同,导致我不同的理解,弄混之前的理解。后现在觉得名字什么的只是一个说法,理解才是最重要的。所以我们可以在应用中针对不同的案例实现不同的继承方法

时间: 2024-08-03 12:48:03

关于面向对象的总结和疑惑(转载可乐冰的相关文章

关于linux下内存使用的一些疑惑[转载]

Linux内存机制-Cache与Buffer 在linux中经常发现空闲内存很少,似乎所有的内存都被系统占用了,表面感觉内存不够用了,其实不然.这是Linux内存管理的一个优秀特性,在这方面,区别于windows的内存管理.主要特点是,无论物理内存有多大,linux都将其充分利用,将一些程序调用过的硬盘数据读入内存,利用内存读写的高速特性来提高Linux系统的数据访问性能.而windows是只在需要内存时,才为应用程序分配内存,并不能充分利用大容量的内存空间.换句话说,每增加一些物理内存,Lin

# 61条面向对象设计的经验原则-《OOD启思录》Arthur J.Riel

61条面向对象设计的经验原则-<OOD启思录>Arthur J.Riel 原文 http://blog.csdn.net/cpluser/article/details/129291 61条面向对象设计的经验原则 摘抄自<OOD 启思录>--Arthur J.Riel 著 鲍志云 译 "你不必严格遵守这些原则,违背它们也不会被处以宗教刑罚.但你应当把这些原则看成警铃,若违背了其中的一条,那么警铃就会响起." ----------Arthur J.Riel (1)

python-装饰器模式

说明: 有时为了给某个对象而不是给整个类添加一个功能,使用继承机制是添加功能的一个有效途径,但是不够灵活,用户不能控制对组件加边框的方式和时机,并且会导致子类膨胀.一种较为灵活的方式就是将组件嵌入另一个对象中,这个嵌入的对象叫做装饰. 装饰模式:动态地给一个对象增加一些额外的职责.就扩展功能而言,装饰模式提供了一种比使用子类更加灵活的替代方案.以对客户透明的方式动态地给一个对象附加上更多的责任 可以在不需要创建更多子类的情况下,让对象的功能得以扩展 装饰模式分析 可以在不改变一个对象本身功能的基

(转载)【笨木头Lua专栏】基础补充20:面向对象——类和继承

终于来了,在Lua中的面向对象编程,相信目前学习Lua的大部分人都是为了开发手机网游吧.而且基本都是奔着脚本语言的热更新特性去的,所以全脚本开发变得十分流行. 对于普及不太广的Lua(相对于C++.Java等主流语言),需要短时间上手开发游戏,对新手而言不算简单.所以大家才更习惯于继续用面向对象思想去折腾Lua吧~ 好了,不唠叨了,我最不喜欢唠叨了.(小若:是是是,你一点都不唠叨,赶紧开讲!) 笨木头花心贡献,哈?花心?不,是用心~ 转载请注明,原文地址:http://www.benmutou.

Lua程序转载 - 面向对象的实现探讨

> 转载出处:http://blog.csdn.net/xenyinzen/article/details/3536708 元表概念     Lua中,面向对向是用元表这种机制来实现的.首先,一般来说,一个表和它的元表是不同的个体(不属于同一个表),在创建新的table时,不会自动创建元表.但是,任何表都可以有元表(这种能力是存在的). e.g.t = {}print(getmetatable(t))   --> nilt1 = {}setmetatable(t, t1)assert(getm

Java基础01 从HelloWorld到面向对象(转载)

Java是完全面向对象的语言.Java通过虚拟机的运行机制,实现“跨平台”的理念. "Hello World!" public class HelloWorld{    public static void main(String[] args){        System.out.println("Hello World!");    }} 程序中包括Java的一些基本特征: 类(class):上面程序定义了一个类HelloWorld,该类的名字与.java文件

(转载)JavaScript中面向对象那点事

鉴于自己在JavaScript这方面比较薄弱,所以就找了一本书恶补了一下(被称为犀利书的JavaScript权威指南).书的内容虽然多了点,但这也充分说明了js中的东西还是挺多的.虽然我们的定位不是前端,但最好还是了解一下js这个发展了将近20年但依然很火的技术. 两年前,写过一篇关于JavaScript闭包的博客,所以对闭包这个词印象很深,在看这书的时候,又看到了闭包,那么这次再看闭包,会有什么不同的理解呢? 大家都知道,在JavaScript中是没有类的概念的,更没有私有.公有的成员变量这样

(转载)【笨木头Lua专栏】基础补充21:面向对象——多重继承、私密性

在Lua中的多重继承和私密性可能用得比较少,也可能只是我个人用得比较少. 本来想偷懒不写这文章的,因为我今天刚买了个漂移板,连起步都还没学会啊,想多学一会. 咳咳,本着坚持不懈.负责到底的态度,我还是决定随便写几句~(小若:随便写几句是几吨意思啊?!) 笨木头花心贡献,哈?花心?不,是用心~ 转载请注明,原文地址:http://www.benmutou.com/archives/1800 文章来源:笨木头与游戏开发 1.多重继承之在多个类中查找一个字段 我发现这些高(shen)智(jing)商(

(转载)Java程序员应当知道的10个面向对象设计原则

面向对象设计原则是OOPS编程的核心, 但我见过的大多数Java程序员热心于像Singleton (单例) . Decorator(装饰器).Observer(观察者) 等设计模式,而没有把足够多的注意力放在学习面向对象的分析和设计上面.学习面向对象编程像"抽象"."封装"."多态"."继承" 等基础知识是重要的,但同时为了创建简洁.模块化的设计,了解这些设计原则也同等重要.我经常看到不同经验水平的java程序员,他们有的不知