可以顺带找到其他文档手册

解构赋值

ES6中的类和对象

创建类

  1. // 1. 创建类 class 创建一个 明星类
  2. class Star {
  3. constructor(uname, age) {
  4. this.uname = uname;
  5. this.age = age;
  6. }
  7. }
  8. // 2. 利用类创建对象 new
  9. var ldh = new Star('刘德华', 18);
  10. var zxy = new Star('张学友', 20);
  11. console.log(ldh);
  12. console.log(zxy);

(1) 通过class 关键字创建类, 类名我们还是习惯性定义首字母大写 (2) 类里面有个constructor 函数,可以接受传递过来的参数,同时返回实例对象 (3) constructor 函数 只要 new 生成实例时,就会自动调用这个函数, 如果我们不写这个函数,类也会自动生成这个函数 (4) 生成实例 new 不能省略 (5) 最后注意语法规范, 创建类 类名后面不要加小括号,生成实例 类名后面加小括号, 构造函数不需要加function

类中添加方法

  1. // 1. 创建类 class 创建一个 明星类
  2. class Star {
  3. // 类的共有属性放到 constructor 里面
  4. constructor(uname, age) {
  5. this.uname = uname;
  6. this.age = age;
  7. }
  8. sing(song) {
  9. // console.log('我唱歌');
  10. console.log(this.uname + song);
  11. }
  12. }
  13. // 2. 利用类创建对象 new
  14. var ldh = new Star('刘德华', 18);
  15. var zxy = new Star('张学友', 20);
  16. console.log(ldh);
  17. console.log(zxy);
  18. // (1) 我们类里面所有的函数不需要写function
  19. // (2) 多个函数方法之间不需要添加逗号分隔
  20. ldh.sing('冰雨');
  21. zxy.sing('李香兰');

类继承

  1. class Father {
  2. constructor(x, y) {
  3. this.x = x;
  4. this.y = y;
  5. }
  6. sum() {
  7. console.log(this.x + this.y);
  8. }
  9. }
  10. class Son extends Father {
  11. constructor(x, y) {
  12. super(x, y); //调用了父类中的构造函数
  13. }
  14. }
  15. var son = new Son(1, 2);
  16. var son1 = new Son(11, 22);
  17. son.sum();
  18. son1.sum();

super关键字

  1. // super 关键字调用父类普通函数
  2. class Father {
  3. say() {
  4. return '我是爸爸';
  5. }
  6. }
  7. class Son extends Father {
  8. say() {
  9. // console.log('我是儿子');
  10. console.log(super.say() + '的儿子');
  11. // super.say() 就是调用父类中的普通函数 say()
  12. }
  13. }
  14. var son = new Son();
  15. son.say();

继承中的属性或者方法查找原则: 就近原则

  1. 继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的
  2. 继承中,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这个方法(就近原则)

注意事项

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <button>点击</button>
  11. <script>
  12. var that;
  13. var _that;
  14. class Star {
  15. constructor(uname, age) {
  16. // constructor 里面的this 指向的是 创建的实例对象
  17. that = this;
  18. console.log(this);
  19. this.uname = uname;
  20. this.age = age;
  21. // this.sing();
  22. this.btn = document.querySelector('button');
  23. this.btn.onclick = this.sing;
  24. }
  25. sing() {
  26. // 这个sing方法里面的this 指向的是 btn 这个按钮,因为这个按钮调用了这个函数
  27. console.log(this);
  28. console.log(that.uname); // that里面存储的是constructor里面的this
  29. }
  30. dance() {
  31. // 这个dance里面的this 指向的是实例对象 ldh 因为ldh 调用了这个函数
  32. _that = this;
  33. console.log(this);
  34. }
  35. }
  36. var ldh = new Star('刘德华');
  37. console.log(that === ldh);
  38. ldh.dance();
  39. console.log(_that === ldh);
  40. </script>
  41. </body>
  42. </html
  1. 在 ES6 中类没有变量提升,所以必须先定义类,才能通过类实例化对象
  2. 类里面的共有的属性和方法一定要加this使用.

构造函数和原型

创建对象三种方式

  1. // 1. 利用 new Object() 创建对象
  2. var obj1 = new Object();
  3. // 2. 利用 对象字面量创建对象
  4. var obj2 = {
  5. uname:'lzx',
  6. age:18
  7. };
  8. // 3. 利用构造函数创建对象
  9. function Star(uname, age) {
  10. this.uname = uname;
  11. this.age = age;
  12. this.sing = function() {
  13. console.log('我会唱歌');
  14. }
  15. }
  16. var ldh = new Star('刘德华', 18);
  17. var zxy = new Star('张学友', 19);
  18. console.log(ldh);
  19. ldh.sing();
  20. zxy.sing();

构造函数

构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与 new 一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。
在 JS 中,使用构造函数时要注意以下两点:

1.构造函数用于创建某一类对象,其首字母要大写 2.构造函数要和 new 一起使用才有意义

new在执行时会做四件事情:
①在内存中创建一个新的空对象。
②让this指向这个新的对象。
③执行构造函数里面的代码,给这个新对象添加属性和方法。
④返回这个新对象(所以构造函数里面不需要return)。

静态成员和实例成员

  1. // 构造函数中的属性和方法我们称为成员, 成员可以添加
  2. function Star(uname, age) {
  3. this.uname = uname;
  4. this.age = age;
  5. this.sing = function() {
  6. console.log('我会唱歌');
  7. }
  8. }
  9. var ldh = new Star('刘德华', 18);
  10. // 1.实例成员就是构造函数内部通过this添加的成员 uname age sing 就是实例成员
  11. // 实例成员只能通过实例化的对象来访问
  12. console.log(ldh.uname);
  13. ldh.sing();
  14. // console.log(Star.uname); // 不可以通过构造函数来访问实例成员
  15. // 2. 静态成员 在构造函数本身上添加的成员 sex 就是静态成员
  16. Star.sex = '男';
  17. // 静态成员只能通过构造函数来访问
  18. console.log(Star.sex);
  19. console.log(ldh.sex); // 不能通过对象来访问

构造函数的问题

image.png

构造函数原型 prototype

构造函数通过原型分配的函数是所有对象所共享的。
JavaScript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象。注意这个 prototype 就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有。
我们可以把那些不变的方法,直接定义在 prototype 对象上,这样所有对象的实例就可以共享这些方法。

  1. // 1. 构造函数的问题.
  2. function Star(uname, age) {
  3. this.uname = uname;
  4. this.age = age;
  5. // this.sing = function() {
  6. // console.log('我会唱歌');
  7. // }
  8. }
  9. Star.prototype.sing = function() {
  10. console.log('我会唱歌');
  11. }
  12. var ldh = new Star('刘德华', 18);
  13. var zxy = new Star('张学友', 19);
  14. console.log(ldh.sing === zxy.sing);
  15. // console.dir(Star);
  16. ldh.sing();
  17. zxy.sing();
  18. // 2. 一般情况下,我们的公共属性定义到构造函数里面, 公共的方法我们放到原型对象身上

使用构造函数创建的对象,定义的方法每次实例化都会为方法对象开辟新的内存空间,浪费内存。所以,一般情况下,我们的公共属性定义到构造函数里面, 公共的方法我们放到原型对象身上

对象原型 proto

对象都会有一个属性 proto 指向构造函数的 prototype 原型对象,之所以我们对象可以使用构造函数 prototype 原型对象的属性和方法,就是因为对象有 proto 原型的存在。
lproto对象原型和原型对象 prototype 是等价的
lproto对象原型的意义就在于为对象的查找机制提供一个方向,或者说一条路线,但是它是一个非标准属性,因此实际开发中,不可以使用这个属性,它只是内部指向原型对象 prototype

constructor 构造函数

对象原型( proto)和构造函数(prototype)原型对象里面都有一个属性 constructor属性 ,constructor 我们称为构造函数,因为它指回构造函数本身。
constructor 主要用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数。
一般情况下,对象的方法都在构造函数的原型对象中设置。如果有多个对象的方法,我们可以给原型对象采取对象形式赋值,但是这样就会覆盖构造函数原型对象原来的内容,这样修改后的原型对象 constructor 就不再指向当前构造函数了。此时,我们可以在修改后的原型对象中,添加一个 constructor 指向原来的构造函数。

构造函数、实例、原型对象三者之间的关系

image.png

原型链

image.png

JavaScript 的成员查找机制(规则)

  1. 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
  2. 如果没有就查找它的原型(也就是 proto指向的prototype 原型对象)。
  3. 如果还没有就查找原型对象的原型(Object的原型对象)。
  4. 依此类推一直找到 Object 为止(null)。
  5. proto对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线

    原型对象this指向

    构造函数中的this 指向我们实例对象.
    原型对象里面放的是方法, 这个方法里面的this 指向的是 这个方法的调用者, 也就是这个实例对象.