概述
学习JS面向对象ES6的第一天
1、两大编程思想
//面向过程(POP)
面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候在一个一个的依次调用
举个例子:将大象装进冰箱,面向过程的做法
(1)打开冰箱门
(2)大象装进去
(3)关上冰箱门
面向过程,就是按照我们分析好了的步骤,按照步骤解决问题
//面向对象(OOP)
面向对象是把事务分解成为一个个对象,然后由对象之间分工和合作
举个例子:将大象装进冰箱,面向对象的做法
先找出对象,并写出这些对象的功能:
1、大象对象
进去
2、冰箱对象
打开
关闭
3、使用大象和冰箱的功能
面向对象是以对象功能来划分问题,而不是步骤
在面向对象程序开发思想中,每一个对象就是功能中心,具有明确分工
面向对象编程具有灵活、代码可复用、容易维护和开发的优点,更适合多人合作的大型软件项目
面向对象的特性:
(1)封装性
(2)继承性
(3)多态性
//面向过程和面向对象的对比
面向过程
优点:性能比面向对象高,适合跟硬件联系很紧密的东西,例如单片机就采用的面向过程编程
缺点:没有面向对象易维护、易复用、易扩展
面向对象
优点:易维护、易封装、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更易于维护
缺点:性能比面向过程低
用面向过程的发放写出来的程序是一份蛋炒饭,而用面向对象写出来的程序是一份盖浇饭
2、面向对象
面向对象更贴近我们的实际生活,可以使用面向对象描述现实世界事物,但是事物分为具体的事物和抽象的事物
举个例子:
手机 抽象的
小米手机 具体的(特指的)
面向对象的思维特点:
1、抽取(抽象)对象共用的属性和行为组织(封装)成一个类(模板)
2、对类进行实例化,获取类的对象
面向对象编程我们考虑的是有哪些对象,按照面向对象的思维特点,不断地创建对象,使用对象,指挥对象做事情
3、对象
现实生活中:万物皆对象,对象是一个具体的事物,看得见摸得着的实物。例如,一本书、一辆汽车、一个人可以是“对象”,一个数据库,一个网页,一个与远程服务器的连接也可以是“对象”。
在Javascript,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等
对象是由属性和方法组成的:
属性:事物的特征,在对象中用属性来表示(常用名词)
方法:事物的行为,在对象中用方法来表示(常用动词)
4、类
在ES6中新增加了类的概念,可以使用class关键字声明一个类,之后以这个类来实例化对象
类抽象了对象的公共部分,它泛指某一大类(class)
对象特指某一个,通过类实例化一个具体的对象
5、创建类
//语法:
class name {
// class body
}
//创建实例:
var xx=new name();
//注意:类必须使用new实例化对象
6、类constructor构造函数
//constructor()方法是类的构造函数(默认方法),用于传递参数,返回实例对象,通过new命令生成对象实例时,自动调用该方法。如果没有显示定义,类内部会自动给我们创建一个constructor()
//1、创建类 class 创建一个明星类
class Star {
constructor(uname) {
this.uname = uname;
}
}
//2、利用类创建对象 new
var ldh = new Star('刘德华');
console.log(ldh.uname);
//'刘德华'作为参数,当用new创建对象时,传递给constructor中的uname,然后uname转递给this.uname,同时返回实例指向ldh
//(1)通过class关键字创建类,类名我们还是习惯性定义首字母大写
//(2)类里面有个constructor函数,可以接受传递过来的参数,同时返回实例对象
//(3)constructor函数只要new生成实例时,就会自动调用这个函数,如果我们不写这个函数,类也会自动生成这个函数
//(4)生成实例 new 不能省略
//(5)最后注意语法规范,创建类 类名后面不要加小括号,生成实例 类名后面加小括号,构造函数不需要加function
7、类中添加方法
//语法
class Person {
constructor(name,age) {
this.name=name;
this.age=age;
}
say() {
console.log(this.name + '你好');
}
}
//1、创建类 class 创建一个明星类
class Star {
constructor(uname,age) {
this.uname = uname;
this.age=age;
}
sing(song) {
//console.log('我唱歌');
console.log(this.name + song);
}
}
//2、利用类创建对象 new
var ldh = new Star('刘德华',18);
console.log(ldh);
ldh.sing('冰雨');
//(1)我们类里面所有的函数不需要写function
//(2)多个函数方法之间不需要添加逗号分隔
8、类的继承
//继承
现实中的继承:子承父业,比如我们都继承了父亲的姓
程序中的继承:子类可以继承父类的一些属性和方法
//语法
class Father { //父类
}
class Son extends Father { //子类继承父类
}
//1、类的继承
//例子1
class Father {
constructor() {
}
money() {
console.log(100);
}
}
class Son extends Father {
}
var son = new Son();
son.money();
9、super关键字
//例子
class Father {
constructor(x,y){
this.x=x;
this.y=y;
}
sum() {
console.log(this.x+this.y);
}
}
class Son extends Father {
constrcutor(x,y) {
this.x=x;
this.y=y;
}
}
var son=new Son(1,2);
//例子现目前开始运行,会报错,报错的原因在于,传入的(1,2)传进了子类的this,但是没有传入父类的this
//super关键字用于访问和调用对象父类上的函数。可以调用父类的构造函数,也可以调用父类的普通函数
class Father {
constructor(x,y){
this.x=x;
this.y=y;
}
sum() {
console.log(this.x+this.y);
}
}
class Son extends Father {
constructor(x,y) {
super(x,y); //调用了父类中的构造函数
}
}
var son=new Son(1,2);
son.sum();
add:构造函数与普通函数的区别
1、命名规则
构造函数名首字母一般大写,普通函数名首字母一般小写
2、调用规则
通过new操作符调用的则是构造函数,否则是普通函数
// 普通函数声明
function run () {
console.log('I can run!!');
}
// 普通函数的调用
console.log(run());
// 构造函数声明
function Person(name,height) {
this.name = name;
this.height =height;
this.say = function (){
console.log('hello');
};
}
// 构造函数的调用
console.log(new Person('mrgao','170'));
3、调用时返回内容不同
上述代码中执行控制台的结果为:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PIz4c2Wx-1662564375952)(JS面向对象ES6.assets/20200829113515302.png)]
从结果中可以看到,假如普通函数中没有设置return的内容,调用后,返回的是undefined。而构造函数则是返回了一个叫Person的对象,至于这个Person对象里面的属性跟方法是怎么来的呢?下面我来为大家一一讲解。
说到这里,不得不说的就是构造函数内部的原理。
执行构造函数的时候,其内部会有一些“隐式”操作,以下是执行构造函数内部时的原理步骤:
1、立刻在堆内存中创建一个新的对象
2、将新建的对象设置为函数中的this
3、逐个执行函数中的代码
4、将新建的对象作为返回值
super关键字调用父类普通函数
//super关键字调用父类普通函数
class Father {
say() {
return '我是爸爸';
}
}
class Son extends Father{
say() {
console.log('我是儿子');
}
}
var son = new Son();
son.say();
//当Son继承Father后,此时上述代码还是输出'我是儿子'(就近原则)
//1、继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的
//2、继承中,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这个方法(就近原则)
//super关键字
//super关键字用于访问和调用对象父类上的函数。可以调用父类的构造函数,也可以调用父类的普通函数
//语法
class Father {
say() {
return '我是爸爸';
}
}
class Son extends Father {
say() {
console.log(super.say() + '的儿子');
}
}
var son = new Son();
son.say();
super必须放到子类this之前(子类继承父类方法同时扩展自己的方法)
class Father {
constructor(x,y) {
this.x=x;
this.y=y;
}
sum() {
console.log(this.x+this.y);
}
}
class Son extends Father {
constructor(x,y) {
this.x=x;
this.y=y;
super(x,y); //注意super与this的书写顺序!!!
}
subtract() {
console.log(this.x-this.y);
}
}
var son=new Son(5,3);
son.subtract();
//以上程序执行完后会报错,super必须在子类的this前调用
10、类和对象三个注意点
第一个注意点
//1、在ES6中类没有变量提升,必须先定义类,才能通过类实例化对象
第二个注意点
//2、类里面的共有属性和方法一定要加this使用
//例子:
class Star {
constructor(uname,age) {
this.uname=uname;
this.age=age;
}
sing() {
console.log(uname);
}
}
var ldh = new Star('刘德华');
ldh.sing();
//此时上述程序执行后会报错,修改程序如下:
class Star {
constructor(uname,age) {
this.uname=uname;
this.age=age;
}
sing() {
console.log(this.uname); //注意看uname前加了this!!!
}
}
var ldh = new Star('刘德华');
ldh.sing();
//例子:
class Star {
constructor(uname,age) {
this.uname=uname;
this.age=age;
sing();
}
sing() {
console.log(this.uname);
}
}
var ldh = new Star('刘德华');
//这次我们不通过ldh.sing()来调用sing方法,而是在constructor中调用
//上述程序会报错,修改如下:
class Star {
constructor(uname,age) {
this.uname=uname;
this.age=age;
this.sing(); //注意看sing()方法前加上了this
}
sing() {
console.log(this.uname);
}
}
var ldh = new Star('刘德华');
//例子:
<button>点击</button>
class Star {
constructor(uname,age) {
this.uname=uname;
this.age=age;
this.btn = document.querySelector('button'); //注意:this.btn
this.btn.onclick = this.sing;//注意:this.sing注意不要加(),因为如果加了()那么就会立马调用,不能实现点击的效果
}
sing() {
console.log(this.uname);
}
}
var ldh = new Star('刘德华');
第三个注意点
//3、类里面的this指向问题
<button>点击</button>
class Star {
constructor(uname,age) {
//constructor里面的this指向的是 创建的实例对象Star
this.uname=uname;
this.age=age;
this.btn = document.querySelector('button');
this.btn.onclick = this.sing;
}
sing() {
//这个sing方法里面的this 指向的是btn这个按钮,因为这个按钮调用了这个函数
console.log(this.uname); //输出undefined,因为button中没有uname的定义
}
dance() {
//这个dance里面的this 指向的是实例对象 ldh 因为ldh 调用了这个函数
console.log(this);
}
}
var ldh = new Star('刘德华');
//如果想在sing里面调用constructor里面的this,则需要设置一个全局变量,同时这个全局变量存储constructor里面的this,再将sing里面对this的引用替换成这个全局变量即可
//例如对上述程序进行修改:
<button>点击</button>
var that; //定义全局变量
class Star {
constructor(uname,age) {
that = this ; //将constructor中的this赋值给全局变量that
this.uname=uname;
this.age=age;
this.btn = document.querySelector('button');
this.btn.onclick = this.sing;
}
sing() {
//console.log(this.uname);
console.log(that.uname); //将这里的this替换成that
}
dance() {
console.log(this);
}
}
var ldh = new Star('刘德华');
11、构造函数和原型
概述
在典型的OOP的语言中(java),都存在类的概念,类就是对象的模板,对象就是类的实例,但在ES6之前,JS中没有引入类的概念
创建对象可以通过以下三种方式:
1、对象字面量
var obj1 = new Object();
2、new Object()
var obj2 = {};
3、自定义构造函数
function Star(uname,age) {
this.uname = uname;
this.age = age;
this.sing = function() {
console.log('我会唱歌');
}
}
var ldh = new Star('刘德华',18);
console.log(ldh);
构造函数
构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面
在JS中,使用构造函数时要注意以下两点:
1、构造函数用于创建某一类对象,其首字母要大写
2、构造函数要和new一起使用才有意义
new在执行时会做四件事情:
1、在内存中创建一个新的空对象
2、让this指向这个新的对象
3、执行构造函数里面的代码,给这个新对象添加属性和方法
4、返回这个新对象(所以构造函数里面不需要return)
静态成员和实例成员
静态成员:在构造函数本上添加的成员称为静态成员,只能由构造函数本身来访问
实例成员:在构造函数内部创建的对象成员称为实例成员,只能有实例化的对象来访问
最后
以上就是小巧煎饼为你收集整理的JS面向对象ES6学习JS面向对象ES6的第一天的全部内容,希望文章能够帮你解决JS面向对象ES6学习JS面向对象ES6的第一天所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复