前端面试之ES6中的继承!

ES6之前并没有给我们提供 extends继承。我们可以通过构造函数+原型对象模拟实现继承,被称为组合继承。

1 call()

两个作用:

1 调用这个函数!

2 修改函数运行时this的指向!

调用方法 某个方法.call()来调用!

第一个参数:当前调用函数this的指向!

后面的参数就是一些普通参数了!

      <script>
// call 方法
function fun(a, b) {
console.log('我被调用了!');
// 原来的this是指向的是window
console.log(this) // window
console.log(a + b);
}
var obj = {
description: '函数fun中的this指向被修改了!由原来的window变成了我!'
}
// 1 call() 可以调用函数
// fun.call()
// 修改函数fun中this的指向!
// 第一个参数是当前调用函数this的指向
// 也就是新的指向对象! obj
// 后面的就是一些普通的参数了!
fun.call(obj, 3, 6);
</script>

2 借用构造函数继承父类型属性!

核心原理:通过call()把父类型的this指向子类型的this,这样就可以实现子类型继承父类型的属性!

   <script>
// 借用父构造函数继承属性!
// 1 父构造函数
function Father(uname, age) {
// 父构造函数中的 this指向父构造函数的对象实例
this.uname = uname;
this.age = age;
}
// 子构造函数
debugger
function Son(uname, age) {
// 子构造函数中的 this指向子构造函数的实例 // 这就是借用父构造函数 改变父构造函数中的this指向!
// 因为当前的this是写在子构造函数里面的!
// 所以也就完成了我们的目标 指向子构造函数当中的this!
// 同时我们也可以使用父构造函数中的
// 属性和方法了!
Father.call(this, uname, age);
} var son = new Son('lvhang', 23);
console.log(son);

借用原型对象继承父类型方法!

注意点: 我们要继承原型对象的方法不能够通过简单的原型对象赋值的方式来实现!

原因:这样直接赋值会有问题, 如果修改了子原型对象, 父原型对象也会跟着一起变化! 这就是所谓的浅拷贝! 只拷贝了地址!

解决方法:我们把父构造函数的实例化对象赋值给子构造函数的原型对象不就可以了吗! 因为父构造函数的实例化对象也能通过对象原型指回父构造函数的原型对象,就能够使用父构造函数中的方法了!同时,父构造函数中也不会有我们子构造函数的方法了 !也就完成了我们的目标 ---- 借用父构造函数中的原型对象来实现继承!

 <script>
// 借用父构造函数继承属性!
// 1 父构造函数
function Father(uname, age) {
// 父构造函数中的 this指向父构造函数的对象实例
this.uname = uname;
this.age = age;
}
// 一些共有的属性放在构造函数中
// 一些共有的方法!放在原型对象上!
Father.prototype.Say2 = function () {
console.log('借用原型对象继承父类型方法!');
} function Son(uname, age) {
// 子构造函数中的 this指向子构造函数的实例
Father.call(this, uname, age);
}
// Son.prototype = Father.prototype; 这样直接赋值会有问题, 如果修改了子原型对象, 父原型对象也会跟着一起变化! 这就是所谓的浅拷贝! 只拷贝了地址!
// 新方式 我们把父构造函数的实例化对象赋值给子构造函数的原型!不就可以了吗!
Son.prototype = new Father();
// 这个是子构造函数专门的方法!
Son.prototype.Say = function () {
console.log('shuo');
}
var son = new Son('lvhang', 23);
console.log(son);
console.log(Father.prototype);
</script>

但是,这样还有一个问题, 就是子构造函数的原型对象会被替换成 父构造函数 哈哈哈哈! 是不是感觉又回到了起点!

 console.log(Son.prototype.constructor);

没事儿 没事儿! 如果利用对象的形式修改了原型对象,别忘了利用constructor 指回原来的构造函数!

        Son.prototype = new Father();
// 1/如果利用对象的形式修改了原型对象,别忘了利用constructor 指回原来的构造函数!
Son.prototype.constructor = Son;

这不就指回了我们的子构造函数了吗!

前端面试之ES6中的继承!的更多相关文章

  1. 前端面试之ES6新增了数组中的的哪些方法?!

    前端面试之ES6新增了数组中的的哪些方法?! 我们先来看看数组中以前有哪些常用的方法吧! 1 新增的方法! 1 forEach() 迭代遍历数组 回调函数中的三个参数 value: 数组中的每一个元素 ...

  2. 前端面试之JavaScript中数组的方法!【残缺版!!】

    前端面试之JavaScript中数组常用的方法 7 join Array.join()方法将数组中所有元素都转化为字符串并连接在-起,返回最后生成的字 符串.可以指定一个可选的字符串在生成的字符串中来 ...

  3. ES5和ES6中的继承 图解

    Javascript中的继承一直是个比较麻烦的问题,prototype.constructor.__proto__在构造函数,实例和原型之间有的 复杂的关系,不仔细捋下很难记得牢固.ES6中又新增了c ...

  4. ES5和ES6中的继承

    看到一篇写的非常好的关于js继承的文章,其中对构造函数.原型.实例之间的关系的描述十分透彻,故转载作者文章以随时学习,并供大家共同进步! ES5 ES5中的继承,看图: function Super( ...

  5. 前端面试之JavaScript中的闭包!

    前端面试之JavaScript中的闭包! 闭包 闭包( closure )指有权访问另一个函数作用域中变量的函数. ----- JavaScript 高级程序设计 闭包其实可以理解为是一个函数 简单理 ...

  6. 大厂HR面试必备ES6中的深入浅出面试题知识点

    ESMAScript6简介,ES6是JavaScript语言的下一代标准,目的是让JavaScript语言可以写复杂的大型应用程序,成为企业级语言.那么ECMAScript和JavaScript的关系 ...

  7. JS创建对象、继承原型、ES6中class继承

    面向对象编程:java中对象的两个基本概念:1.类:类是对象的模板,比如说Leader 这个是泛称领导,并不特指谁.2:实例:实例是根据类创建的对象,根据类Leader可以创建出很多实例:liyi,y ...

  8. ES5和ES6中对于继承的实现方法

    在ES5继承的实现非常有趣的,由于没有传统面向对象类的概念,Javascript利用原型链的特性来实现继承,这其中有很多的属性指向和需要注意的地方. 原型链的特点和实现已经在之前的一篇整理说过了,就是 ...

  9. ES5与ES6中的继承

    ES5继承在ES5中没有类的概念,所以一般都是基于原型链继承,具体的继承方法有以下几种: 父类: function Father (name) { this.name = name || 'sam' ...

随机推荐

  1. Java进阶:基于TCP通信的网络实时聊天室

    目录 开门见山 一.数据结构Map 二.保证线程安全 三.群聊核心方法 四.聊天室具体设计 0.用户登录服务器 1.查看当前上线用户 2.群聊 3.私信 4.退出当前聊天状态 5.离线 6.查看帮助 ...

  2. C#中未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序

    解决方法 方法一 "设置应用程序池默认属性"/"常规"/"启用32位应用程序",设置为 true. 方法二 生成->配置管理器-> ...

  3. ConcurrentHashMap线程安全吗?

    前言 没啥深入实践的理论系同学,在使用并发工具时,总是认为把HashMap改为ConcurrentHashMap,就完美解决并发了呀.或者使用写时复制的CopyOnWriteArrayList,性能更 ...

  4. oracle 19c dataguard aws ORA-03186报错

    环境说明 在亚马逊云AWS上面安装了一套oracle 19c dataguard,linux centos 7.7的操作系统,开始时同步正常,实时应用redolog,一会儿之后就不行了.报错如下: o ...

  5. 高并发redis分布式锁

    1.方法一 2方法二

  6. @Transient 注解

    使用 @Transient 表示该属性并非是一个要映射到数据库表中的字段,只是起辅助作用.ORM框架将会忽略该属性

  7. mysql字符串拼接

    逗号分隔拼接字符串 SELECT group_concat(USER_ID)from rocky_bankinfo         默认大小2014 2).可以简单一点,执行语句,可以设置作用范围   ...

  8. Qt学习笔记-设计简易的截图工具软件

    现在利用Qt来实现一个截图软件. 首先,设计一个界面出来. 最上面有一个label用来显示图片. 然后使用QPixmap中的静态函数grabWindow来获取图片.这里需要一个winID.可以使用 Q ...

  9. JavaDailyReports10_09

    ***************************** 1.2.2 布局管理器 BorderLayout 把容器的布局分为东西南北中五个部位,默认是中间,平铺占满! 1 package awt; ...

  10. jit编译原理

    jit用以把程序全部或部分翻译成本地机器码,当需要装载某个类[通常是创建第一个对象时],编译器会先找到其.class文件,然后将该类的字节码装入内存. hotspot采用惰性评估法: 如果一段代码频繁 ...