赞
踩
1 对象的方法补充
2 原型继承关系图
3 class方式定义类
4 extends实现继承
5 extends实现继承
6 多态概念的理
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>
-
- var obj = {
- running: function() {},
- eating: () => {},
- swimming() {
-
- }
- }
-
- // function Person() {
-
- // }
-
- // Person.prototype.running = function() {
-
- // }
-
- // 编程: 高内聚低耦合
- class Person {
- // 1.类中的构造函数
- // 当我们通过new关键字调用一个Person类时, 默认调用class中的constructor方法
- constructor(name, age) {
- this.name = name
- this.age = age
- }
-
- // 2.实例方法
- // 本质上是放在Person.prototype
- running() {
- 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>
可以把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 = name this.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 = name this.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>
- <!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>
- <!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 = x
- this.y = y
- this.width = width
- this.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>
- <!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 = name
- this.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>
- <!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() {
- console.log("running~")
- }
- eating() {
- console.log("eating~")
- }
-
- }
-
- class Student extends Person {
- constructor(name, age, sno, score) {
- // this.name = name
- // this.age = age
- super(name, age)
- this.sno = sno
- this.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 = age
- super(name, age)
- this.title = title
- }
-
- // running() {
- // console.log("running~")
- // }
- // eating() {
- // console.log("eating~")
- // }
-
- teaching() {
- console.log("teaching~")
- }
- }
-
-
- </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>
-
- 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>
- <!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>
<!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。
- <!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 = width
- this.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>
- <!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 = 123
- foo = "Hello World"
- console.log(foo.split())
- foo = {
- running: function() {}
- }
- foo.running()
- foo = []
- console.log(foo.length)
-
- </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.属性的增强
- 2.方法的增强
- 3.计算属性名的写法
- */
-
- var name = "why"
- var age = 18
-
- var 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>
- <!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"] = names
- console.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 = "中国"
- } = obj
- console.log(wName, wAge, wHeight, wAddress)
-
- // 2.5. 对象的剩余内容
- var {
- name,
- age,
- ...newObj
- } = obj
- console.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>
- <!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.prototype
- function foo(name, age) {
- console.log(this, name, age)
- }
-
- // foo函数可以通过apply/call
- // foo.apply("aaa", ["why", 18])
- // foo.call("bbb", "kobe", 30)
-
- // 1.给函数对象添加方法: hyapply
- Function.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 = this
- Object.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.给函数对象添加方法: hycall
- Function.prototype.hycall = function(thisArg, ...otherArgs) {
- // 1.获取thisArg, 并且确保是一个对象类型
- thisArg = (thisArg === null || thisArg === undefined)? window: Object(thisArg)
-
- // thisArg.fn = this
- Object.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>
- <!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.prototype
- function 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 = this
- Object.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 = this
- Object.defineProperty(thisArg, "fn", {
- enumerable: false,
- configurable: true,
- value: this
- })
- thisArg.fn(...otherArgs)
-
- delete thisArg.fn
- }
-
-
- // 1.给函数对象添加方法: hyapply
- Function.prototype.hyapply = function(thisArg, otherArgs) {
- this.hyexec(thisArg, otherArgs)
- }
- // 2.给函数对象添加方法: hycall
- Function.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>
- <!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/call
- function 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>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。