JavaScript ES6实现继承

1 对象的方法补充

2 原型继承关系图

3 class方式定义类

4 extends实现继承

5 extends实现继承

6 多态概念的理

function 创建的名称如果开头是大写的,那这个创建的不是函数,是创建了类。

 ES6-class类中的内容

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>var obj = {running: function() {},eating: () => {},swimming() {}}// function Person() {// }// Person.prototype.running = function() {// }// 编程: 高内聚低耦合class Person {// 1.类中的构造函数// 当我们通过new关键字调用一个Person类时, 默认调用class中的constructor方法constructor(name, age) {this.name = namethis.age = age}// 2.实例方法// 本质上是放在Person.prototyperunning() {console.log(this.name + " running~")}eating() {console.log(this.name + " eating~")}}// 创建实例对象var p1 = new Person("why", 18)// 使用实例对象中属性和方法console.log(p1.name, p1.age)p1.running()p1.eating()// 研究内容console.log(Person.prototype === p1.__proto__)console.log(Person.running) // 不能调用console.log(Person.prototype.running) // 可以调用</script></body>
</html>

ES6-class和function类的区别

可以把class创建的类当做是function创建的类的一种语法糖。但是在直接使用的方面是有不同之处。类里面的方法又叫静态方法。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>// function定义类function Person1(name, age) {this.name = namethis.age = age}Person1.prototype.running = function() {}Person1.prototype.eating = function() {}var p1 = new Person1("why", 18)console.log(p1.__proto__ === Person1.prototype)console.log(Person1.prototype.constructor)console.log(typeof Person1) // function// 不同点: 作为普通函数去调用Person1("abc", 100)// class定义类class Person2 {constructor(name, age) {this.name = namethis.age = age}running() {}eating() {}}var p2 = new Person2("kobe", 30)console.log(p2.__proto__ === Person2.prototype)console.log(Person2.prototype.constructor)console.log(typeof Person2)// 不同点: class定义的类, 不能作为一个普通的函数进行调用Person2("cba", 0)</script></body>
</html>

ES6-对象访问器方法的编写

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>// 针对对象// 方式一: 描述符// var obj = {// _name: "why"// }// Object.defineProperty(obj, "name", {//   configurable: true,//   enumerable: true,//   set: function() {//   },//   get: function() {//   }// })// 方式二: 直接在对象定义访问器// 监听_name什么时候被访问, 什么设置新的值var obj = {_name: "why",// setter方法set name(value) {this._name = value},// getter方法get name() {return this._name}}obj.name = "kobe"console.log(obj.name)</script></body>
</html>

ES6-类的访问器方法的编写

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>// 1.访问器的编写方式// class Person {//   // 程序员之间的约定: 以_开头的属性和方法, 是不在外界访问//   constructor(name, age) {//     this._name = name//   }//   set name(value) {//     console.log("设置name")//     this._name = value//   }//   get name() {//     console.log("获取name")//     return this._name//   }// }// var p1 = new Person("why", 18)// p1.name = "kobe"// console.log(p1.name)// // console.log(p1._name)// var p2 = new Person("james", 25)// console.log(p2.name)// 2.访问器的应用场景class Rectangle {constructor(x, y, width, height) {this.x = xthis.y = ythis.width = widththis.height = height}get position() {return { x: this.x, y: this.y }}get size() {return { width: this.width, height: this.height }}}var rect1 = new Rectangle(10, 20, 100, 200)console.log(rect1.position)console.log(rect1.size)</script></body>
</html>

ES6-类的静态方法的编写

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>// function Person() {}// // 实例方法// Person.prototype.running = function() {}// // 类方法// Person.randomPerson = function() {}// var p1 = new Person()// p1.running()// Person.randomPerson()// class定义的类var names = ["abc", "cba", "nba", "mba"]class Person {constructor(name, age) {this.name = namethis.age = age}// 实例方法running() {console.log(this.name + " running~")}eating() {}// 类方法(静态方法)static randomPerson() {console.log(this)var randomName = names[Math.floor(Math.random() * names.length)]return new this(randomName, Math.floor(Math.random() * 100))}}var p1 = new Person()p1.running()p1.eating()var randomPerson = Person.randomPerson()console.log(randomPerson)</script></body>
</html>

ES6-通过extends实现继承

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>// 定义父类class Person {constructor(name, age) {this.name = namethis.age = age}running() {console.log("running~")}eating() {console.log("eating~")}}class Student extends Person {constructor(name, age, sno, score) {// this.name = name// this.age = agesuper(name, age)this.sno = snothis.score = score}// running() {//   console.log("running~")// }// eating() {//   console.log("eating~")// }studying() {console.log("studying~")}}var stu1 = new Student("why", 18, 111, 100)stu1.running()stu1.eating()stu1.studying()class Teacher extends Person {constructor(name, age, title) {// this.name = name// this.age = agesuper(name, age)this.title = title}// running() {//   console.log("running~")// }// eating() {//   console.log("eating~")// }teaching() {console.log("teaching~")}}</script></body>
</html>

ES6-super关键字的其他用法

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>class Animal {running() {console.log("running")}eating() {console.log("eating")}static sleep() {console.log("static animal sleep")}}class Dog extends Animal {// 子类如果对于父类的方法实现不满足(继承过来的方法)// 重新实现称之为重写(父类方法的重写)running() {console.log("dog四条腿")// 调用父类的方法super.running()// console.log("running~")// console.log("dog四条腿running~")}static sleep() {console.log("趴着")super.sleep()}}var dog = new Dog()dog.running()dog.eating()Dog.sleep()</script></body>
</html>

继承自内置类的用法

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>// 1.创建一个新的类, 继承自Array进行扩展class HYArray extends Array {get lastItem() {return this[this.length - 1]}get firstItem() {return this[0]}}var arr = new HYArray(10, 20, 30)console.log(arr)console.log(arr.length)console.log(arr[0])console.log(arr.lastItem)console.log(arr.firstItem)// 2.直接对Array进行扩展Array.prototype.lastItem = function() {return this[this.length - 1]}var arr = new Array(10, 20, 30)console.log(arr.__proto__ === Array.prototype)console.log(arr.lastItem())// 函数apply/call/bind方法 -> Function.prototype</script></body>
</html>

ES6-类的混入mixin的用法

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>// JavaScript只支持单继承(不支持多继承)function mixinAnimal(BaseClass) {return class extends BaseClass {running() {console.log("running~")}}}function mixinRunner(BaseClass) {return class extends BaseClass {flying() {console.log("flying~")}}}class Bird {eating() {console.log("eating~")}}// var NewBird = mixinRunner(mixinAnimal(Bird))class NewBird extends mixinRunner(mixinAnimal(Bird)) {}var bird = new NewBird()bird.flying()bird.running()bird.eating()</script></body>
</html>

ES6-ES6中的class转ES5代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>// class Person {//   constructor(name, age) {//     this.name = name//     this.age = age//   }//   running() {}//   eating() {}//   static randomPerson() {}// }// var p1 = new Person()</script><script src="./js/es5_code01.js"></script></body>
</html>

可以去babel官网打开try out,然后改default。

ES6-Java面向对象的多态理解

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>// 继承是多态的前提// shape形状class Shape {getArea() {}}class Rectangle extends Shape {constructor(width, height) {super()this.width = widththis.height = height}getArea() {return this.width * this.height}}class Circle extends Shape {constructor(radius) {super()this.radius = radius}getArea() {return this.radius * this.radius * 3.14}}var rect1 = new Rectangle(100, 200)var rect2 = new Rectangle(20, 30)var c1 = new Circle(10)var c2 = new Circle(15)// 表现形式就是多态/*在严格意义的面向对象语言中, 多态的是存在如下条件的:1.必须有继承(实现接口)2.必须有父类引用指向子类对象*/function getShapeArea(shape) {console.log(shape.getArea())}getShapeArea(rect1)getShapeArea(c1)var obj = {getArea: function() {return 10000}}getShapeArea(obj)getShapeArea(123)</script></body>
</html>

ES6-JS面向对象的多态理解

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>// 多态的表现: JS到处都是多态function sum(a1, a2) {return a1 + a2}sum(20, 30)sum("abc", "cba")// 多态的表现var foo = 123foo = "Hello World"console.log(foo.split())foo = {running: function() {}}foo.running()foo = []console.log(foo.length)</script></body>
</html>

ES6-对象字面量的增强写法

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>/*1.属性的增强2.方法的增强3.计算属性名的写法*/var name = "why"var age = 18var key = "address" + " city"var obj = {// 1.属性的增强name,age,// 2.方法的增强running: function() {console.log(this)},swimming() {console.log(this)},eating: () => {console.log(this)},// 3.计算属性名[key]: "广州"}obj.running()obj.swimming()obj.eating()function foo() {var message = "Hello World"var info = "my name is why"return { message, info }}var result = foo()console.log(result.message, result.info)</script></body>
</html>

ES6-数组和对象的解构语法

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>var names = ["abc", "cba", undefined, "nba", "mba"]// 1.数组的解构// var name1 = names[0]// var name2 = names[1]// var name3 = names[2]// 1.1. 基本使用// var [name1, name2, name3] = names// console.log(name1, name2, name3)// 1.2. 顺序问题: 严格的顺序// var [name1, , name3] = names// console.log(name1, name3)// 1.3. 解构出数组// var [name1, name2, ...newNames] = names// console.log(name1, name2, newNames)// 1.4. 解构的默认值var [name1, name2, name3 = "default"] = namesconsole.log(name1, name2, name3)// 2.对象的解构var obj = { name: "why", age: 18, height: 1.88 }// var name = obj.name// var age = obj.age// var height = obj.height// 2.1. 基本使用// var { name, age, height } = obj// console.log(name, age, height)// 2.2. 顺序问题: 对象的解构是没有顺序, 根据key解构// var { height, name, age } = obj// console.log(name, age, height)// 2.3. 对变量进行重命名// var { height: wHeight, name: wName, age: wAge } = obj// console.log(wName, wAge, wHeight)// 2.4. 默认值var { height: wHeight, name: wName, age: wAge, address: wAddress = "中国"} = objconsole.log(wName, wAge, wHeight, wAddress)// 2.5. 对象的剩余内容var {name,age,...newObj} = objconsole.log(newObj)// 应用: 在函数中(其他类似的地方)//  function getPosition(position)直接把position解构成{ x, y },方便拿对象里面的参数function getPosition({ x, y }) {console.log(x, y)}getPosition({ x: 10, y: 20 })getPosition({ x: 25, y: 35 })function foo(num) {}foo(123)</script></body>
</html>

补充-手写apply-call函数实现

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>// new Function()// foo.__proto__ === Function.prototypefunction foo(name, age) {console.log(this, name, age)}// foo函数可以通过apply/call// foo.apply("aaa", ["why", 18])// foo.call("bbb", "kobe", 30)// 1.给函数对象添加方法: hyapplyFunction.prototype.hyapply = function(thisArg, otherArgs) {// this -> 调用的函数对象// thisArg -> 传入的第一个参数, 要绑定的this// console.log(this) // -> 当前调用的函数对象// this.apply(thisArg)thisArg.fn = this// 1.获取thisArg, 并且确保是一个对象类型thisArg = (thisArg === null || thisArg === undefined)? window: Object(thisArg)// thisArg.fn = thisObject.defineProperty(thisArg, "fn", {enumerable: false,configurable: true,value: this})thisArg.fn(...otherArgs)delete thisArg.fn}// foo.hyapply({ name: "why" }, ["james", 25])// foo.hyapply(123, ["why", 18])// foo.hyapply(null, ["kobe", 30])// 2.给函数对象添加方法: hycallFunction.prototype.hycall = function(thisArg, ...otherArgs) {// 1.获取thisArg, 并且确保是一个对象类型thisArg = (thisArg === null || thisArg === undefined)? window: Object(thisArg)// thisArg.fn = thisObject.defineProperty(thisArg, "fn", {enumerable: false,configurable: true,value: this})thisArg.fn(...otherArgs)delete thisArg.fn}foo.hycall({ name: "why", fn: "abc" }, "james", 25)foo.hycall(123, "why", 18)foo.hycall(null, "kobe", 30)</script></body>
</html>

补充-手写apply-call抽取封装

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>// new Function()// foo.__proto__ === Function.prototypefunction foo(name, age) {console.log(this, name, age)}// foo函数可以通过apply/call// foo.apply("aaa", ["why", 18])// foo.call("bbb", "kobe", 30)// 1.封装思想// 1.1.封装到独立的函数中function execFn(thisArg, otherArgs, fn) {// 1.获取thisArg, 并且确保是一个对象类型thisArg = (thisArg === null || thisArg === undefined)? window: Object(thisArg)// thisArg.fn = thisObject.defineProperty(thisArg, "fn", {enumerable: false,configurable: true,value: fn})// 执行代码thisArg.fn(...otherArgs)delete thisArg.fn}// 1.2. 封装原型中Function.prototype.hyexec = function(thisArg, otherArgs) {// 1.获取thisArg, 并且确保是一个对象类型thisArg = (thisArg === null || thisArg === undefined)? window: Object(thisArg)// thisArg.fn = thisObject.defineProperty(thisArg, "fn", {enumerable: false,configurable: true,value: this})thisArg.fn(...otherArgs)delete thisArg.fn}// 1.给函数对象添加方法: hyapplyFunction.prototype.hyapply = function(thisArg, otherArgs) {this.hyexec(thisArg, otherArgs)}// 2.给函数对象添加方法: hycallFunction.prototype.hycall = function(thisArg, ...otherArgs) {this.hyexec(thisArg, otherArgs)}foo.hyapply({ name: "why" }, ["james", 25])foo.hyapply(123, ["why", 18])foo.hyapply(null, ["kobe", 30])foo.hycall({ name: "why" }, "james", 25)foo.hycall(123, "why", 18)foo.hycall(null, "kobe", 30)</script></body>
</html>

补充-手写bind函数的实现

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>// apply/callfunction foo(name, age, height, address) {console.log(this, name, age, height, address)}// Function.prototype// var newFoo = foo.bind({ name: "why" }, "why", 18)// newFoo(1.88)// 实现hybind函数Function.prototype.hybind = function(thisArg, ...otherArgs) {// console.log(this) // -> foo函数对象thisArg = thisArg === null || thisArg === undefined ? window: Object(thisArg)Object.defineProperty(thisArg, "fn", {enumerable: false,configurable: true,writable: false,value: this})return (...newArgs) => {// var allArgs = otherArgs.concat(newArgs)var allArgs = [...otherArgs, ...newArgs]thisArg.fn(...allArgs)}}var newFoo = foo.hybind("abc", "kobe", 30)newFoo(1.88, "广州市")newFoo(1.88, "广州市")newFoo(1.88, "广州市")newFoo(1.88, "广州市")</script></body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/19892.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CUDA编程实战(使用Sobel算子对rgb图片进行边缘检测)

写在前面&#xff0c;本篇文章为一个CUDA实例&#xff0c;使用GPU并行计算对程序进行加速。如果不需要看环境如何配置&#xff0c;可以直接到看代码部分:点击直达 关于如何更改代码和理解代码写在这个地方:点击直达 运行环境&#xff1a; 系统:windows10专业版 显卡:NVIDIA …

uniapp 在app中获取经纬度

在uniapp中app端&#xff0c;uni.getLocation获取经纬度会有大概1-2公里的偏差&#xff0c;在实际项目中&#xff0c;有的需求对经纬度的准确度要求比较严格&#xff0c;研究了很多种方式&#xff0c;最终发现使用高德地图api的微信小程序的插件获取的准确性是最准的&#xff0…

vue3前端模拟https安全策略同局域网内测试方法-local-ssl-proxy

文章目录 前言建议全局安装运行安全策略模拟运行效果如果其他客户端不能访问 直接在cmd跑即可&#xff0c;不过我们应该先运行项目 前言 为什么要用https安全策略呢&#xff0c;因为http浏览器策略访问权限有限&#xff0c;不能使用navigator的激活“用户音频或视频”的方法&a…

解密Vue 2的Diff算法:如何实现高效的DOM更新?

文章目录 1. 虚拟DOM2. Diff算法深度优先遍历双端比较 3. Diff优化策略&#xff1a;为了提高Diff算法的效率&#xff0c;Vue采用了一些优化策略&#xff1a;4.对Vue 2中Diff算法的规划进行表格总结附录&#xff1a;「简历必备」前后端实战项目&#xff08;推荐&#xff1a;⭐️…

SpringBoot 异常处理机制

SpringBoot中异常处理的流程图 在SpringBoot项目中&#xff0c;如果业务逻辑发生了异常&#xff0c;则首先看发生异常的类中有没有ExceptionHandle能处理&#xff0c;如果能&#xff0c;则执行方法进行处理&#xff0c;如果没有&#xff0c;则去找全局的ControllerAdvice注解…

34.RocketMQ之Broker端消息存储流程详解

highlight: arduino-light Broker消息存储概要设计 RocketMQ主要存储的文件包括Commitlog文件&#xff0c;ConsumeQueue文件&#xff0c;IndexFile文件。 RMQ把所有主题的消息存储在同一个文件中&#xff0c;确保消息发送时顺序写文件。 为了提高消费效率引入了ConsumeQueue消息…

云原生(第六篇)k8s-kubeadmin部署

master&#xff08;2C/4G&#xff0c;cpu核心数要求大于2&#xff09; 192.168.169.10 docker、kubeadm、kubelet、kubectl、flannel node01&#xff08;2C/2G&#xff09; 192.168.169.30 docker、kubeadm、kubelet、kubect…

如何解决git中拉取或提交代码出现的ssl证书问题?

问题描述 执行命令的时候&#xff0c;出现"…certificate problem…"报错&#xff0c;一般在执行"git push“ (推送分支) 或者 “git clone”(克隆仓库)时出现&#xff0c;原因时因为SSL安全验证问题&#xff0c;不能获取到本地的的证书。那么如何解决这个问题…

SpringBoot 如何使用 MockMvc 进行 Web 集成测试

SpringBoot 如何使用 MockMvc 进行 Web 集成测试 介绍 SpringBoot 是一个流行的 Java Web 开发框架&#xff0c;它提供了一些强大的工具和库&#xff0c;使得开发 Web 应用程序变得更加容易。其中之一是 MockMvc&#xff0c;它提供了一种测试 SpringBoot Web 应用程序的方式&…

Microsoft Remote Desktop for mac安装教程

适用于Mac的Microsoft远程桌面测试版&#xff01;Microsoft Remote Desktop Beta for Mac是一种远程工具&#xff0c;允许用户从Mac远程访问基于Windows的计算机。使用此工具&#xff0c;用户可以随时随地使用Mac连接到远程桌面、应用程序和资源。 Microsoft Remote Desktop B…

2023年Arm最新处理器架构分析——X4、A720和A520

1、引言 上一篇文章我们介绍了Arm的Cortex-X1至Cortex-X3系列处理器&#xff0c;2023年的5月底&#xff0c;Arm如期发布了新一年的处理器架构&#xff0c;分别为超级大核心Cortex-X4&#xff0c;大核心A720和小核心A520。在智能手机行业&#xff0c;Arm始终保持每年一迭代的处…

【GCD+MST】ABC210 E

这道题告诉我们&#xff0c;一道题一定要去手摸样例&#xff0c;多造几个数据&#xff0c;然后找思路 很多时候&#xff0c;题目看错了&#xff0c;码完发现思路错了&#xff0c;调半天调不出来&#xff0c;思路一直在旧框架打转&#xff0c;这些情况都是不去考察实际情况导致…