JS 详解对象的继承
在学习这篇博文前,请先移步我的另外一篇博文:JS 一张图理解prototype、proto和constructor的关系,先弄清楚“原型链”,这样对于理解继承会非常有效。
注意:博文中提到的“属性”,指的是“属性+方法”,这里统称为“属性”;
一、构造函数继承
var obj = new Object(); 使用构造函数new一个对象实例(所以程序员天天都在谈对象,哈哈哈)
特点:
- 实例对象继承父类的共有属性和私有属性
来个实例加深理解:
function Animal() {
this.type = '动物';
}
Animal.prototype.getType = function(){
console.log(this.type);
}
let animal = new Animal();
console.log(animal.type); // 动物
animal.getType(); // 动物
二、原型链继承
Child.prototype = new Parent(); 将父类的实例作为子类的原型
特点:
- 子类的prototype上的所有属性将被完全覆盖,所以子类的prototype属性应该在覆盖后重新定义;
- 子类的constructor指向父类,为了构造函数的完整性,需要重新指定子类的constructor属性,方法:Child.prototype.constructor = Child;
- 修改子类与父类同名的属性,不会修改父类的属性;这是因为父类的属性在子类的原型链上,且这些属性相当于是子类的__prototype__或者更加上一级。(这里如果理解不了,说明没理解透 JS 一张图理解prototype、proto和constructor的关系 这篇文章)
来个实例加深理解:
function Animal() {
this.type = '动物';
}
Animal.prototype.getType = function(){
console.log(this.type);
}
function Cat(){
this.vary = '猫';
}
Cat.prototype.getVary = function(){
console.log(this.vary);
}
Cat.prototype = new Animal();
var cat = new Cat();
// cat.getVary() // 报错:cat.getVary is not a function [原因:Cat.prototype = new Animal()的操作覆盖了原型链]
console.log(cat.constructor); // Animal 这个constructor实质调用的是Animal.prototype.constructor
// 修改Cat类的constructor为Cat
Cat.prototype.constructor = Cat;
console.log(cat.constructor); // Cat
cat.getType(); // 动物
// 修改Cat类prototype上的getType方法,看是否影响Animal类的getType方法
Cat.prototype.getType = function(){
console.log('我是猫科类');
}
var animal = new Animal();
animal.getType(); // 动物
三、call、apply、bind继承
在子类的构造体中,使用call、apply、bind方法,让父类方法中的this指向子类的实例,也就是改变this的上下文环境。
特点:
- 子类构造体继承父类的私有属性(继承完成后,子类和父类是没关系的)
先来个call实现原理,很重要的哦
Function.prototype.call2 = function () {
var ary = [...arguments].slice();
if (!arguments[]) {
this(...ary);
} else {
var obj = Object(arguments[]); // 将参数变成一个对象
obj.__proto__.fn = this;
obj.fn(...ary);
delete obj.__proto__.fn;
}
};
来个实例加深理解:
function Animal() {
this.type = '动物';
}
Animal.prototype.getType = function(){
console.log(this.type);
}
function Cat(){
Animal.call(this);
this.vary = '猫';
}
Cat.prototype.getVary = function(){
console.log(this.vary);
}
var cat = new Cat();
console.log(cat.type); // 动物
// cat.getType(); // Uncaught TypeError: cat.getType is not a function
cat.type = '猫科动物';
var animal = new Animal();
console.log(animal.type); // 动物
四、寄生组合继承
var child = Object.create(obj, props);
- obj:一个对象,应该是新创建的对象的原型。
- props:可选。该参数对象是一组属性与值,该对象的属性名称将是新创建的对象的属性名称,值是属性描述符
我先来一段Object.create的实现方式(看懂原理很重要)
Object.create = function (o) {
var F = function () {};
F.prototype = o;
return new F();
};
我们这里只分析参数obj的骚操作,可以看出来,Object.create是内部定义一个对象,并且让F.prototype对象赋值为引进的对象/函数 o,并return出一个对象的实例。
只要看懂了原理,我们可以参考“原型链继承”的方式去理解这种继承方法;
来个实例加深理解:
function Animal() {
this.type = '动物';
}
Animal.prototype.getType = function(){
console.log(this.type);
}
var cat = Object.create(new Animal(), {
vary: {
value: '猫科动物'
}
});
console.log(cat.constructor); // Animal 这个constructor实质调用的是Animal.prototype.constructor
console.log(cat.type); // 动物
cat.getType(); // 动物
console.log(cat.vary); // '猫科动物'
JS 详解对象的继承的更多相关文章
- 详解Javascript的继承实现(二)
上文<详解Javascript的继承实现>介绍了一个通用的继承库,基于该库,可以快速构建带继承关系和静态成员的javascript类,好使用也好理解,额外的好处是,如果所有类都用这种库来构 ...
- 【three.js详解之一】入门篇
[three.js详解之一]入门篇 开场白 webGL可以让我们在canvas上实现3D效果.而three.js是一款webGL框架,由于其易用性被广泛应用.如果你要学习webGL,抛弃那些复杂的 ...
- 【three.js详解之二】渲染器篇
[three.js详解之二]渲染器篇 本篇文章将详细讲解three.js中渲染器(renderer)的设置方法. three.js文档中渲染器的分支如下: Renderers CanvasRend ...
- dev-server.js详解
转载自:https://www.cnblogs.com/ye-hcj/p/7091706.html dev-server.js详解 require('./check-versions')() var ...
- webpack.dev.conf.js详解
转载自:https://www.cnblogs.com/ye-hcj/p/7087205.html webpack.dev.conf.js详解 //引入当前目录下的utils.js文件模块var ut ...
- JS 详解 Cookie、 LocalStorage 与 SessionStorage-转载
记录一下这些知识,有时候用到会忘记,对原文作者表达感谢. 附上原文链接:JS 详解 Cookie. LocalStorage 与 SessionStorage 基本概念 Cookie Cookie 是 ...
- [js高手之路]深入浅出webpack系列2-配置文件webpack.config.js详解
接着上文,重新在webpack文件夹下面新建一个项目文件夹demo2,然后用npm init --yes初始化项目的package.json配置文件,然后安装webpack( npm install ...
- [js高手之路]深入浅出webpack教程系列3-配置文件webpack.config.js详解(下)
本文继续接着上文,继续写下webpack.config.js的其他配置用法. 一.把两个文件打包成一个,entry怎么配置? 在上文中的webpack.dev.config.js中,用数组配置entr ...
- [js高手之路]深入浅出webpack教程系列2-配置文件webpack.config.js详解(上)
[js高手之路]深入浅出webpack教程系列索引目录: [js高手之路]深入浅出webpack教程系列1-安装与基本打包用法和命令参数 [js高手之路]深入浅出webpack教程系列2-配置文件we ...
随机推荐
- Visual Studio VS使用freopen调试控制台闪退
解决方法 freopen("CON", "r", stdin); system("pause>nul"); 暂停函数之前,使用f ...
- 深入理解JVM(8)——类加载的时机
一.类的生命周期 一个类从加载进内存到卸载出内存一共要经历7个阶段:加载—>验证—>准备-->解析—>初始化—>使用—>卸载. 类加载包括五部分:加载—>验证 ...
- Java基础知识总结--String、StringBuffer、StringBuilder
1.Java String 类 String类是final类,也即意味着String类不能被继承,并且它的成员方法都默认为final方法.在Java中,被final修饰的类是不允许被继承的,并且该类中 ...
- 微信小程序-图片预览
仅供参考: 1,wxml: <view class="foot" bindtap="previewImage">我的小程序码</view> ...
- Python3爬虫实例 代理的使用
现在爬虫越来越难了,一些网站会有相应的反爬虫措施,例如很多网站会检测某一段时间某个IP的访问次数,如果访问频率太快以至于看起来不像正常访客,它可能就会会禁止这个IP的访问. 所以我们需要设置一些代理服 ...
- curl命令转换成php源码
curl命令转换成php源码 获取状态: curl -X GET -H "Content-Type:application/json" -H "Authorization ...
- InfluxDB meta文件解析
操作系统 : CentOS7.3.1611_x64 go语言版本:1.8.3 linux/amd64 InfluxDB版本:1.1.0 influxdb默认配置: /etc/influxdb/infl ...
- springboot-admin自定义事件通知
springboot-admin组建已经提供了很多开箱即用的通知器(例如邮件),但在有些业务场景下我们需要做一些企业内部的通知渠道,这就需要我们来自定义通知器. 实现其实很简单,只需要往spring注 ...
- 《图解HTTP》——返回结果的 HTTP 状态码
状态码概述 状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果.借助状态码,用户可以知道服务器端是正常处理了请求,还是出现了错误. 状态码如 200 OK,以 3 位数字和原因短语组成.数 ...
- ffmpeg -i 10.wmv -c:v libx264 -c:a aac -strict -2 -f hls -hls_list_size 0 -hls_time 5 C:\fm\074\10\10.m3u8
ffmpeg -i 10.wmv -c:v libx264 -c:a aac -strict -2 -f hls -hls_list_size 0 -hls_time 5 C:\fm\074\10\1 ...