一。基础认知

构造方法有点类似构造函数,前面学的构造函数是模拟类的,ES6用类即可

不能直接调用Person()报错,和构造函数不同,构造函数不加new调用也不报错;

一般在constructor里面加一些初始化的东西;

实例的属性在构造方法里添加,方法不能,因为多个实例就有多个函数会开辟多个内存

不同对象属性应该不一样,但是方法可以公用,传不同参数即可

class类里构造方法和实例方法语法都要用对象里方法的简洁表示法,去掉冒号和function,但是注意没有逗号和分号

在构造方法外添加实例能使用的方法有两种(添加到类原型上和添加到实例本身上)一个是fn:function() {}  和赋值表示法 fn = function() {},我们这里用第一个的简洁表示法添加到类的原型上共享,因为第二个在给实例添加方法是真添加到实例身上,浪费内存

注意,构造函数外写的属性age sex(非方法)是不会加到原型上,方法仅限于简洁表示法才能添加到原型上,构造方法里面的属性方法都是加到实例上;类里面给实例添加的属性或者类本身的属性都只能用等号的方式添加(构造函数中前面要有this);不能用age:12或者static age :12;

注意下面的getSex和speak都是方法名,是字符串,不是变量名

检测Person类型是function,证明底层还是构造函数的原理


本质上方法也是加在构造函数(类)的prototype对象上,和构造函数类似

    <script>
// 1.认识 Class
// 人类:类
// 具体的人:实例、对象 // 类可以看做是对象的模板,用一个类可以创建出许多不同的对象 // 2.Class 的基本用法
// 类名一般大写
// class Person {} √
// class Person() {} ×
// class Person {}; ×
// function func() {} // class Person {
// // 实例化时执行构造方法,所以必须有构造方法,但可以不写出来
// constructor(name, age) {
// // console.log('实例化时执行构造方法');
// this 代表实例对象,上面定义的是实例属性/方法
// this.name = name;
// this.age = age; // // 一般在构造方法中定义属性,方法不在构造方法中定义
// // this.speak = () => {};
// } // // speak:function(){} // // 各实例共享的方法
// speak() {
// console.log('speak');
// }
// } // // Person();
// const zs = new Person('ZS', 18);
// const ls = new Person('LS', 28);
// // console.log(zs.name);
// // console.log(zs.age);
// // console.log(zs.speak);
// zs.speak();
// // console.log(ls.name);
// // console.log(ls.age);
// // console.log(ls.speak);
// console.log(zs.speak === ls.speak); // 3.Class 与构造函数
class Person {
constructor(name, age) {
this.name = name;
this.age = age; // this.speak = () => {};
} speak() {
console.log('speak');
} // run(){}
}
// Person.prototype.run = function () {}; // console.log(typeof Person);
// console.log(Person.prototype.speak); // function Person(name, age) {
// this.name = name;
// this.age = age; // // this.speak = () => {};
// }
// Person.prototype.speak = function () {};
</script>

二。声明方式

立即执行的类就是定义和实例化一起;


    <script>
// 1.声明形式
// class Person {
// constructor() {} // speak() {}
// } // 2.表达式形式
// function Person(){}
// const Person = function () {}; // const Person = class {
// constructor() {
// console.log('constructor');
// } // speak() {}
// };
// new Person(); // (function () {
// console.log('func');
// })();
// func() // 立即执行的匿名类
new (class {
constructor() {
console.log('constructor');
}
})();
// new Person();
</script>

三。class的属性和方法

不仅在构造方法里可以添加实例的属性,如下的方式也可以添加,相当于是实例属性的默认值,列出来一目了然可以看到有哪些属性;和构造方法里给实例添加属性一样,只是不需要this;图中框住部分也可以添加默认方法;给实例添加方法刚刚前面说过了,一样的;



注意静态方法和属性写在和构造方法平行的,而不是写在构造方法里面;静态方法和实例方法定义类似,区别就是前面多个static,不过静态方法简洁表示法或者赋值都可以;

静态属性也可以在类外面加,Person.version = 1.0;

注意,类的静态属性,方法在定义完成后类自己就可以使用;类里面定义的实例共享方法也是定义完就可以使用(方法已经绑定到类的原型上了),不需要实例化后才能使用;

    <script>
// 1.实例属性
// 方法就是值为函数的特殊属性
// class Person {
// age = 0;
// sex = 'male';
// getSex = function () {
// return this.sex;
// }; // constructor(name, sex) {
// this.name = name;
// // this.age = 18;
// this.sex = sex;
// } // // speak() {
// // this.age = 18;
// // }
// } // const p = new Person('Alex');
// console.log(p.name);
// console.log(p.age); // 2.静态方法
// 类的方法
// class Person {
// constructor(name) {
// this.name = name;
// } // speak() {
// console.log('speak');
// console.log(this);
// } // // static speak() {
// // console.log('人类可以说话'); // // // this 指向类
// // console.log(this);
// // }
// } // // Person.speak = function () {
// // console.log('人类可以说话');
// // console.log(this);
// // }; // const p = new Person('Alex');
// p.speak(); // Person.speak(); // 3.静态属性
// 类的属性
class Person {
constructor(name) {
this.name = name;
} // 不要这么写,目前只是提案,有兼容性问题
// static version = '1.0'; static getVersion() {
return '1.0';
}
}
// Person.version = '1.0'; const p = new Person('Alex');
console.log(p.name); // console.log(Person.version);
console.log(Person.getVersion());
</script>

注意,类里面的静态方法、实例方法、构造方法后面都没有逗号和分号

四。私有属性和方法

私有:类中的方法和属性只能在类的内部使用,不能在类的外部使用

注意:下面演示的是实例的属性私有,并不是类本身的属性的私有

公开的话会造成有时候不小心修改了属性值 比如不小心p.name = xxx 覆盖了原来了

ES6没有原生语法支持所以要模拟私有属性和方法

模拟私有:我们想访问name属性里面的值,可以利用函数返回值的方式;

下划线是不成文的规定,约束力不大

立即执行函数模拟模块,模块可以防止全局污染,把声明类放到模块里,其他代码放到另一个模块里

只能通过getName这个接口获取到name值

移出类:在类外面用个变量代替,弊端就是破坏了类的封装,因为本该属于类内部的东西

查看代码
     <script>
// 1.为什么需要私有属性和方法
// 一般情况下,类的属性和方法都是公开的
// 公有的属性和方法可以被外界修改,造成意想不到的错误
// class Person {
// constructor(name) {
// this.name = name;
// } // speak() {
// console.log('speak');
// } // getName() {
// return this.name;
// }
// }
// const p = new Person('Alex');
// console.log(p.name);
// p.speak(); // // ....
// p.name = 'zs';
// console.log(p.name); // 2.模拟私有属性和方法
// 2.1._ 开头表示私有
// class Person {
// constructor(name) {
// this._name = name;
// } // speak() {
// console.log('speak');
// } // getName() {
// return this._name;
// }
// }
// const p = new Person('Alex');
// // console.log(p.name);
// p.name = 'zd';
// console.log(p.getName()); // 2.2.将私有属性和方法移出类 (function () {
let name = ''; class Person {
constructor(username) {
// this.name = name;
name = username;
} speak() {
console.log('speak');
} getName() {
return name;
}
} window.Person = Person;
})(); (function () {
const p = new Person('Alex');
console.log(p.name);
console.log(p.getName());
})();

五。继承exends

不需要实例化只要extends这句代码就实现了原型链的三角关系

证明了Teacher.prototype是Person的实例

下面两句就是继承的结果

上图解释了Teacher实例可以使用父类里面的实例共享方法,因为在原型链上;Teacher类可以使用(父类)Person类的属性和方法,因为也在原型链上

实例子类时,子类构造方法执行,super()执行,调用父类的构造方法,父类构造方法执行,这时父类构造方法里面的this指向子类的实例(很好理解,因为是给子类实例添加属性方法所以this指向子类的实例)-----这也可以叫继承,继承父类构造方法里面的属性

父类里面的东西(属性方法)全部都能继承;同名覆盖,是在子类中又单独写了一下,但是在子类中单独写出来的就是加到子类原型上(子类实例的共享方法)以及子类本身上(静态属性方法),而不是继承的了;同名覆盖是原型链的遮蔽,属性名相同时候优先调用离自己最近的属性;而不是修改了原来继承的那个方法、属性;

this.feature不要放到super之前,会报错

    <script>
// 1.子类继承父类
class Person {
constructor(name, sex) {
this.name = name;
this.sex = sex; this.say = function () {
console.log('say');
};
} speak() {
console.log('speak');
} static speak() {
console.log('static speak');
}
}
Person.version = '1.0'; // class Programmer extends Person {
// constructor(name, sex) {
// super(name, sex);
// }
// } // const zs = new Programmer('zs', '男');
// console.log(zs.name);
// console.log(zs.sex);
// zs.say();
// zs.speak();
// Programmer.speak();
// console.log(Programmer.version); // 2.改写继承的属性或方法
class Programmer extends Person {
constructor(name, sex, feature) {
// this.feature = feature; × // this 操作不能放在 super 前面
super(name, sex); // this.feature = feature;
} hi() {
console.log('hi');
} // 同名覆盖
speak() {
console.log('Programmer speak');
} static speak() {
console.log('Programmer static speak');
}
}
Programmer.version = '2.0'; const zs = new Programmer('zs', '男', '秃头');
console.log(zs.name);
console.log(zs.sex);
console.log(zs.feature);
zs.say();
zs.speak();
zs.hi();
Programmer.speak();
console.log(Programmer.version);
</script>

  六。super

super作为对象在子类构造方法中使用 this问题

在子类中定义了与父类同名的speak方法,会把父类中的speak方法遮蔽掉(子类实例根据原型链就近原则调用speak方法),如果想保留父类中speak方法里的操作,可以在子类的speak方法中,调用一下父类的speak方法;

注意,类里面不要写语句,下面注释部分都报错;只能写属性和方法且要注意语法和对象不一样;

关于类里面哪些代码在还没实例的时候已经执行了,以及继承时的这个情况:

静态的以及实例共享的方法都不需要实例化就已经添加上了!

这个color也是相当于写在父类构造方法中

下面这个可以作为拓展:

super作为对象使用时,使用super调用父类里面的静态方法,实例共享方法也好,注意方法里面的this指向;其他时候的this是符合this指向规则的

理解prototype时,把类当作构造函数;

当子类继承父类时,如果不需要通过constructor设置属性和继承父类constructor中的属性,那么就可以不写constructor和super,否则,就必须写上constructor和super。子类中的constructor和super必须同时存在或者同时不存在;

七。class的应用-- 幻灯片的切换

基类写底层都适用的功能,比如pc端幻灯片,移动端幻灯片继承基类,子类中写具体pc端代码或者移动端代码

ES6-Class类上的更多相关文章

  1. React和ES6(二)ES6的类和ES7的property initializer

    React与ES6系列: React与ES6(一)开篇介绍 React和ES6(二)ES6的类和ES7的property initializer React与ES6(三)ES6类和方法绑定 React ...

  2. [js高手之路] es6系列教程 - new.target属性与es5改造es6的类语法

    es5的构造函数前面如果不用new调用,this指向window,对象的属性就得不到值了,所以以前我们都要在构造函数中通过判断this是否使用了new关键字来确保普通的函数调用方式都能让对象复制到属性 ...

  3. ES6入门——类的概念

    1.Class的基本用法 概述 JavaScript语言的传统方式是通过构造函数,定义并生成新对象.这种写法和传统的面向对象语言差异很大,下面是一个例子: function Point(x, y) { ...

  4. JavaScript es6 class类的理解。

    本着互联网的分享精神,在本篇文章我将会把我对JavaScript  es6 class类的理解分享给大家. JavaScript 类主要是 JavaScript 现有的基于原型的继承的语法糖. 类语法 ...

  5. ES6 | class类的基本语法总结

    类和模块的内部,默认就是严格模式,所以不需要使用use strict指定运行模式.只要你的代码写在类或模块之中,就只有严格模式可用. 考虑到未来所有的代码,其实都是运行在模块之中,所以 ES6 实际上 ...

  6. es6 --- class 类的继承使用

    传统的javascript中只有对象,没有类的概念.它是基于原型的面向对象语言.原型对象特点就是将自身的属性共享给新对象.这样的写法相对于其它传统面向对象语言来讲,很有一种独树一帜的感脚!非常容易让人 ...

  7. ES6 class类中定义私有变量

    ES6 class类中定义私有变量 class类的不足 看起来, es6 中 class 的出现拉近了 JS 和传统 OOP 语言的距离.但是,它仅仅是一个语法糖罢了,不能实现传统 OOP 语言一样的 ...

  8. ES6——class类继承(读书笔记)

    前言 我一定是一个傻子,昨天这篇文章其实我已经写好了一半了,但是我没有保存 这是学习ES6的过程,我没有系统的看完阮大大的书.零零散散的,很多功能知道,但是没有实际的用过 看了几遍,总是看前面几章,所 ...

  9. ES6 class 类的理解(一)

    优点 ES6 的类提供了几点明显的好处: 兼容当前大量的代码. 相对于构造器和构造器继承,类使初学者更容易入门. 子类化在语言层面支持. 可以子类化内置的构造器. 不再需要继承库:框架之间的代码变得更 ...

  10. 在Eclipse中设置Java类上面的注释(包含作者、日期等)

    希望在Eclipse中,让Java类上面的注释像下面这样,改如何设置呢? 在Eclipse中,点击菜单中的Window-->Preferences,打开如下窗口:

随机推荐

  1. STM32F4库函数初始化系列:三重ADC——DMA

    1 void _DMA_Configuration(void) 2 { 3 DMA_InitTypeDef DMA_InitStructure; 4 5 /* DMA2 Stream0 channel ...

  2. Golang HTTP编程及源码解析

    1.网络基础 基本TCP客户-服务器程序Socket编程流程如如下图所示. TCP服务器绑定到特定端口并阻塞监听客户端端连接, TCP客户端则通过IP+端口向服务器发起请求,客户-服务器建立连接之后就 ...

  3. echar 多个图形显示时,点击显示隐藏然后样式缺失,变得非常小

    原因:Echarts 图表是根据你定义的div 的样式来确定图表的大小,当图表隐藏时,Echarts会找不到div的宽和高,再次显示时它会给自己一个非常小的默认宽高值,所以在隐藏显示后会发现它变得非常 ...

  4. Word 设置脚注和尾注

    描述 脚注一般位于页面的底部,作为文档某处内容的注释.尾注一般位于文档的末尾,列出引文的出处等. 设置脚注和尾注 将光标移动到要插入脚注或尾注的地方,然后点击"引用"选项卡. 左边 ...

  5. 基于PostGIS使用GeoServer发布数据量大的GPS轨迹路线图

    1. 引言 人类在行走或者驾驶过程中产生的GPS轨迹,是道路的一种采样,根据GPS轨迹路线,我们可以推知道路的存在,根据轨迹的密度,可以推知道路的热度以及重要性.如何才能在地图中显示大量的轨迹,这是一 ...

  6. ASP.NET Core - 依赖注入(四)

    4. ASP.NET Core默认服务 之前讲了中间件,实际上一个中间件要正常进行工作,通常需要许多的服务配合进行,而中间件中的服务自然也是通过 Ioc 容器进行注册和注入的.前面也讲到,按照约定中间 ...

  7. python编辑excel表格文件的简单方法练习

    一.创建一个Excel文件from openpyxl import Workbook #需要用到openpyxl模块来操作Excel文件.openpyxl需要先安装.#实例化对象wb = Workbo ...

  8. LeetCode-851 喧嚣与富有

    来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/loud-and-rich 题目描述 有一组 n 个人作为实验对象,从 0 到 n - 1 编号, ...

  9. Day 13 13.3 Cookie与Session

    Cookie 一.什么是cookie? cookie的本质就是一组数据(键值对的形式存在) 是由服务器创建,返回给客户端,最终会保存在客户端浏览器中. 如果客户端保存了cookie,则下次再次访问该服 ...

  10. Word14 互联网络发展状况统计报告office真题

    1.课程的讲解之前,先来对题目进行分析,首先需要在考生文件夹下,将Wrod素材.docx文件另存为Word.docx,后续操作均基于此文件,否则不得分. 2.这一步非常的简单,打开下载素材文件,在[文 ...