关于面向对象的总结和疑惑(转载可乐冰
在这节,老师讲了面向对象的三大特性: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);
})()
对于原型继承我的理解是:它和之前说的原型链继承有同样的弊端,不利于每个实例对象的属性状态的不同的保存。
这种继承还存在兼容性,我们可以封装一个函数解决。
以上就是我对继承的理解,因为还是学生,没有实践经历,理解层次还处于理论阶段,可以在以后实践会有不同吧!慢慢来。
在前端自学的路上,遇到好多问题,想对继承方法的命名不同,导致我不同的理解,弄混之前的理解。后现在觉得名字什么的只是一个说法,理解才是最重要的。所以我们可以在应用中针对不同的案例实现不同的继承方法
转载于:https://www.cnblogs.com/sakurashadow/p/5530752.html
关于面向对象的总结和疑惑(转载可乐冰相关推荐
- 【转载】冰美人淘宝装修教程--索引
转载之冰美人社区,链接中可能有误,希望指出,谢谢,同时欢迎大家去这个社区看看,教程不错 ====================================== 冰美人设计淘宝装修基础课更新完毕 ...
- 面向对象的软件测试技术
相关知识点-面象对象(=Object Oriented)技术 1. 对象和类 l 面象对象的编程语言:以对象为中心,以消息为驱动,程序=对象+消息 l 类是一种新的数据类型,是设计的核心,是通过抽象数 ...
- 大家一起学面向对象设计模式系列Chapter 02 软件设计的基本原则
我们为什么要使用设计模式呢?有人可能会说为了设计出"高内聚低耦合"的软件."高内聚低耦合"的软件实际上也就是本文所说的具有可维护性和可复用性的软件. 这篇文章主 ...
- JAVA面向对象初步知识总结:封装、继承、多态
1.封装 把数据和方法包装进类中,以及具体实现的隐藏,常共同被称作是是封装.其结果是一个同时带有特征和行为的数据类型. 所谓具体实现的隐藏是通过访问权限控制实现的. JAVA 子类重写继承的方法时,不 ...
- 面向对象编程思想概览(三)继承
一.简介 本讲以大家耳熟能详的<西游记>中的唐僧师徒四人为例,介绍了类的继承的概念和实现方法,总结了继承的特性和优点,帮助同学们理解面向对象编程中继承的用法,进而掌握面向对象程序设计的基本 ...
- 用星际争霸讲解面向对象的概念
2019独角兽企业重金招聘Python工程师标准>>> 在学习PHP的时候,感觉自己对面向对象理解还不深刻,很多时候是一头雾水.通过别人的推荐,找到了这篇通过星际争霸来讲解面向对象概 ...
- 2018.11.19-day21 初识面向对象 VS 人狗大战
1.初识面向对象 2.人狗大战 转载于:https://www.cnblogs.com/studybrother/p/9985814.html
- 【面向对象】第四单元UML总结及面向对象课程学期总结
目录 一.第四单元的架构设计 第一次UML作业 第二次UML作业 二.四个单元中架构设计及OO方法理解的演进 三.四个单元中测试理解与实践的演进 四.总结自己的课程收获 五.对面向对象课程的建议 一. ...
- 设计模式学习笔记-原型模式
一.概述 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象: 二.模式中的角色 Prototype:声明一个克隆自身的接口: ConcretePrototype:实现一个克隆自身的操作: ...
最新文章
- 为什么现在改用int.TryParse了
- python【蓝桥杯vip练习题库】BASIC-17矩阵乘法(枚举)
- python字典排序取最值总结
- CentOS启动不显示图形界面直接进入命令行模式
- cf 1062d 思维 欧拉筛变形
- 如何画出几种常见二分类损失函数(附代码)
- 构建可扩展的有状态服务
- Mac 神兵利器(三) 使用Intellij IDEA打造全栈IDE
- node.weiChat
- Edge 浏览器启动加载页面修改
- linux 股票指南针,Android 利用方向传感器实现 指南针
- 影像组学在医学影像中的应用
- python读取oracle数据库性能_python 连接oracle数据库,报错解决,pandas读取。
- 2022海南最新消防设施操作员模拟考试试题及答案
- 初中动画flash作品_初中动画flash作品_初中Flash动画设计基础知识试题及答案.doc...
- CTF编码和加密总结
- c语言错误c4047,c语言错误 apos;int apos; differs in levels of indirection from apos;int *apos;...
- Excel如何对一首韩文歌曲进行中文翻译?
- 编写一函数,由实参传来一个字符串,统计此字符串中字母、数字、空格和其它字符的个数,在主函数中输入字符串以及输出上述结果。 只要结果,别输出什么提示信息。
- 什么是设计?设计为什么需要准则?
热门文章
- 计算机基础知识在线作业,福建师范大学《计算机应用基础》在线作业一答案.docx...
- html弹窗确认取消公告代码,js 弹出确认与取消对话框的四种方法
- mysql os.pid_离线安装Mysql
- php webstorm,webstorm和phpstorm的区别
- python调用libs.dbutil_Python 使用 PyMysql、DBUtils 创建连接池,提升性能
- react实战项目_前端学习路线图--从网页设计到项目开发
- js遍历追加html子样式,前端基本功:JS(十一)动画封装(CSS样式获取、JSON遍历)...
- r语言聚类分析_「SPSS数据分析」SPSS聚类分析(R型聚类)的软件操作与结果解读...
- elasticsearch如何安全重启节点
- elasticsearch源码分析之search模块(server端)