# js面向对象的编程基础
> 今天面试的时候和HR谈了很久,其中问道了面向对象的编程的基础。自己回答的不算太好吧,虽然回答了绝大部分。今天就做个简单的总结吧
### 简单的继承
`
~~~
// parentClass
function superclass () {
this.superValue = 'this is parentClass';
}
~~~
// 添加原型共有方法
superclass.prototype.getsuperVaule = function () {
return this.superValue;
}
// childrenClass
function subclass () {
this.subclass = 'this is childclass';
}
//添加子类原型共有方法
subclass.prototype = new superClass();
//为子类添加构造方法
subclass.prototype.getVaule = function () {
return this.subValue;
}
`
## 测试使用
~~~
var instance = new subClass();
console.log(instance.getValue)
console.log(instance.getsuperValue)
~~~
## 解析
其实本质也就是通过将父类的实例赋给子类。之所以将父类实例化,是因为,类要通过prototype才可以访问prototype上面的方法。而对象(也就是类的实例化)可以直接访问(内部是通过__proto__)prototype的方法。子类也是同理了。当我们使用new运算符的时候。对象也就可以访问到prototype上面的方法了。
## 缺点
1. prototype上面的方法是所以子类公用的。如果是引用类型的变量,那么所有的子类都只有公用一个变量。也就是一个子类改变了引用类型的值,其他子类的引用类型的值也会改变。
2. 无法向父类传递参数,初始化父类。毕竟我们是通过父类的实例化赋值给子类的原型。所以在子类实例化的时候。父类早就定下来了。
## 构造函数的继承(经典继承)
~~~
function superclass (item) {
this.subjects = ['html','css','js'];
this.subjects.push(item)
}
//添加原型共有方法
superclass.prototype.each = function () {
this.subjects.forEach( (item,index) => {
console.log(item)
}
}
// 声明子类
function subclass (item) {
superclass.call(this,item)
}
~~~
## 测试
~~~
var instance = new subclass('king')
console.log(instance.subjects)
var instance2 = new subclass('luckyman')
console.log(instance2.subjects)
instance2.each(); //会报错
~~~
## 解析
核心就是通过call或者apply来改变this的指向。将父类的this改变为子类的this。也因为这样子。父类的this上的方法或者属性就会定义到子类当中。但是在父类的原型里的this还是指向父类的。(this指向函数赖以执行的环境,可以认为prototype的执行环境永远都是本身类)。也因此原型上的方法都是无法被继承的。
## 缺点
1. 无法公用变量或者属性。原型上的方法也无法被继承
## 组合继承
~~~
function supclass(item) {
//值类型共有变量
this.name = name
//引用类型共有属性
this.books = ['html','css','js']
item && this.books.push(item)
}
//原型方法
superclass.prototype.each() {
this.books.forEach( (item,index) => {
console.log(item);
}
}
//声明子类
function subclass(item,time) {
supclass.call(this,item);
this.time = time
}
//子类原型
subclass.prototype = new supclass();
//子类原型方法
subclass.prototype.getTime = function () {
console.log(this.time)
}
~~~
## 测试
~~~
var instance1 = new subclass('js book',2017');
instance1.each();
instance1.getTime();
var instance2 = new subclass('高级教程', '2014');
instance2.each();
instance2.getTime();
~~~
## 解析
组合模式本质就是原型继承和构造函数继承两种方式的组合,继承两种方式的优点
## 缺点
开销比较大,在子类的原型上,new了一次父类,在构造函数里又执行了new运算符
所以父类执行了两次初始化
## 原型式继承
~~~
function inheritobject (0) {
//声明过度对象
function F() {}
F.prototype = o;
//返回过度对象的实例,该实例的原型继承了父类
return new F();
}
~~~
### 解析
这种因为构造函数基本没有任何的开销,也可以将F过度类缓存起来。这也是Object.create()方法的实现原理。
### 缺点
1. 引用类型会被所有子类公用
## 寄生继承
~~~
function createObj (obj) {
// 通过原型继承方式创建新对象
var o = new inheriteobject(obj);
// 扩展新对象
o.getName = function () {
console.log(name)
}
// 返回对象
return o;
}
~~~
### 测试
~~~
var books = {
name : 'kingEND',
age: 23
}
var subbooks = new createObj (books);
subooks.getName();
~~~
## 最后的继承者 -- 寄生组合式继承
~~~
function inheritPrototype (subclass, superclass) {
// 复制一份父类的原型副本保存在变量中
var p = inheritobject(supclass.prototype);
//修正因为重写子类原型导致子类的constructor 属性被修改
// 因为p是父类的prototype,所以constructor会指向父类的构造函数
// 而子类的prototype里的constructor应该是指向子类的构造函数
p.constructor = subclass;
// 设置子类的原型
subclass.prototype = p;
}
- 前端
- pc端
- 京东无延时菜单效果
- datapicker组件的编写
- cursor禁止默认样式
- 移动端
- web在真机调试
- 有关vue的上拉加载
- 下拉刷新
- vue获取dom节点
- worker技术
- h5页面唤醒手机拨号,发短信功能
- 弹出层唤醒挤压css背景图片
- 23模式
- 基础模式
- SMD同步模块
- canvas
- 点的均匀分布
- 线条绘画
- canvas常见的全局属性
- 判断点在某个区间内
- 保证动画效果的流畅性
- arc函数学习
- cookies
- 本地服务搭建
- Mint UI框架的学习
- 第一天
- Swiper组件的解析
- loadmore组件
- 二维码的生成
- 前端优化
- 浏览器缓存
- indexdb本地数据库的使用
- 浅谈前端优化
- css渐变属性
- 前端常用组件学习
- picker组件
- vue
- 模块下的state访问
- vue的进阶
- npm包的发布
- 淘宝移动端适配问题
- vue的生命周期的理解
- vue的路由学习
- vue自带的动画效果
- vue 项目里,img标签报错,添加默认图片
- axios 实现loading加载提示
- qs库
- vue的v-for指令无法使用在tr、td中
- vue打包之后,npm run dev 空白
- vue 单页面百度统计
- unix时间转化
- UI组件的实现
- picker
- upload组件
- js动画效果
- canvas甜甜圈的编写
- 瀑布流实现
- 适配问题
- 图片加载
- js基础知识
- js数组合并
- 响应布局总结
- 组件开发
- grid组件
- 专题页面常用布局页面
- scroll滚动问题
- 项目整理经验收集
- 画图工具应用实现记录
- 参考线实现
- JCode
- 多条件筛选不用ajax的原因分析
- node
- koa路由下的分块
- 连接数据库mysql
- 初步搭建数据库模型
- java
- spring框架的学习
- maven 搭建web项目
- 建站
- 关联github
- 杂文
- 后端常用成熟系统
- node实战练习
- 编写邮箱通知
- 微信小程序
- 模板之坑
- 模板坑之数据传入
- 小程序组件化之一
- 有关this的绑定
- 小程序组件化之二
- 小程序分包加载
- tab切换,页面状态不更新
- 小程序请求组件(草稿)
- php学习之路
- 文件上传
- 有关数据库时间类型的插入
- Ubuntu下的php开启扩展模块
- windows系统下的hosts文件位置
- 腾讯云的cos
- thinkPHP
- 模块设计
- 模型的使用
- ajax的请求异常总结
- apache服务器
- 虚拟主机的建立
- ssh的使用
- ftp服务器配置
- Lamp的搭建
- ftp从零开始配置
- https的配置
- git hooks实现简单的自动部署
- ubuntu系统登录远程ubuntu服务器
- ubuntu
- 新建用户需要使用sudo
- sftp的文件上传问题
- 配置apache部分问题总结
- git服务器的搭建
- githook的学习
- ubuntu 虚拟主机搭建
- ubunut的服务器的防火墙的关闭
- 宝塔部署laravel
- 关于宝塔phpmyadmin无法访问的问题
- 解决码云每次提交输入密码的问题
- mysql
- phpmyadmin的安装
- 远程登陆数据库
- git的使用
- 拉去分支的代码
- git remote指令
- 学习临时笔记
- ios兼容性问题
- 苹果获取屏幕宽度问题
- toDataURL无法导出图片
- 苹果触屏滚动,下拉刷新问题
- jquery动画
- jquery的animate无法使用transform
- jquery队列queue
- css重学之路
- 规范一
- css3的matrix属性
- 淘宝适配方案
- Yii框架学习
- gd库的支持安装
- larval框架学习
- 中间件
- 指令
- 自定义指令生成token
- 微信登录后端篇
- 宝塔apache配置ssl
- SVN
- PS
- 快捷键
- Redis
- Redis在Unbtun下的配置
- 微信公众号开发
- 测试号配置