js高级(半)

一、面向对象的编程介绍

1. 面向过程编程pop

  • 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一 步实现 ,使用的时候再一个一 个的依次调用就可以了。

  • 例子:将大象装进冰箱,面向过程做法。
    1.开冰箱门

    2.把大象放进去

    3.关上冰箱门

2. 面向对象编程oop

  • 把事务分解成一个个对象,然后由对象之间分工与合作

  • 例子:将大象装进冰箱,面向对象做法。

    先找出对象,并写出这些对象的功能:
    1.大象对象
    进去

    2.冰箱对象
    打开
    关闭

    3.使用大象和冰箱的功能

在面向对象程序开发思想中,每一一个对象都是功能中心,具有明确分工。

面向对象编程具有灵活、代码可复用、容易维护和开发的优点,更适合多人合作的大型软件项目。

面向对象的特性:

  • 封装性

  • 继承性

  • 多态性

3. 面向过程和面向对象的对比

二、ES6中的类和对象

1. 对象

对象是由属性和方法组成的:

属性:事物的特征,在对象中用属性来表示(常用名词)
方法:事物的行为,在对象中用方法来表示(常用动词)

2. 方法

在ES6中新增加了类的概念,可以使用class关键字声明一个类,之后以这个类来实例化对象。

3. 创建类

语法:

class name {
//class body
}

创建实例:

var xx = new name();

4. 类 constructor 构造函数

  • constructor() 方法是类的构造函数(默认方法),用于传递参数,返回实例对象,

  • 通过 new 命令生成对象实例时,自动调用该方法。

  • 如果没有显示定义, 类内部会自动给我们创建一个constructor()。

<script>
//1.创建类 class 创建一个明星类
class Star {
constructor(uname,age){//类里面的构造函数
this.uname = uname;
this.age = age;
}
}
//2.利用类创建对象new
var ldh= new Star('刘德华',18);
var zxy= new Star('张学友',20);
console.log(ldh);
console.log(zxy);
</script>

5. 类中添加方法

//1.创建类 class 创建一个明星类
class Star {
//类的共有属性放到 constructor 里面
constructor(uname,age){//类里面的构造函数
this.uname = uname;
this.age = age;
}
say(){
console.log(this.uname + '你好');
}
}

6. 继承

子类可以继承父类中的一些属性和方法。

class Father{//父类
constructor(){
}
money(){
console.log(100);
}
}
class Son extends Father{//子类继承父类
}
var son = new Son();
son.money();

6.1 super关键字

super 关键字用于访问和调用对象父类上的函数,可以调用父类的构造函数,也可以调用父类的普通函数。

1. 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);
var son1 = new Son(11,22);
son.sum();
son1.sum();

2. super 关键字 调用父类的普通函数

语法:

//super关键字调用父类普通函数
class Father {
say(){
return '我是爸爸';
}
}
class Son extends Father {
say(){
// console.log('我是儿子');
console.log(super.say()+'的儿子');
// super.say()就是调用父类中的普通函数 say()
}
}
var son = new Son();
son.say();
  • 继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的

  • 继承中,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这个方法(就近原则)

3.super必须放到子类this之前

<script>
//父类有加法方法
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调用父类的构造函数
//super必须在子类this之前调用
super(x,y);
this.x = x;
this.y = y;
}
subtract(){
console.log(this.x - this.y);
}
}
var son = new Son(5,2);
son.sum();
son.subtract();
</script>

注意:子类在构造函数中使用super,必须放到this前面(必须先调用父类的构造方法,再使用子类构造方法)

7. ES6中的类和对象使用时的三个注意点

三个注意点:

  • 在ES6中类没有变量提升,所以必须先定义类,才能通过类实例化对象

  • 类里面的共有属性和方法一定要加 this 使用

  • 类里面的 this 指向问题:

    • constructor 里面的 this 指向创建的实例对象,

    • 方法里面的 this 指向这个方法的调用者
      father.sum();//调用者是father
      this.sum();//调用者是this
      this.btn.onclick = this.sum;//调用者是btn

<button>click</button>
<script>
var that
class Father {
constructor(x, y) {
that = this;//这里的that===this
this.x = x;
this.y = y;
// this.sum();//实例化时直接调用该方法
this.btn = document.querySelector('button')
this.btn.onclick = this.sum;//加了()后会立即调用,而不是点击后调用
}
sum() {
console.log(that.x + that.y);//这里的that就是实例对象
}
}
var father = new Father(1, 5)
father.sum();
</script>

三、构造函数和对象

在ES6之前,对象不是基于类创建的,而是用一种称为构造函数的特殊函数来定义对象和它们的特征。

创建对象可以通过以下三种方式:

  • 对象字面量

  • new Object()

  • 自定义构造函数

1.构造函数

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

在JS中,使用构造函数时要注意以下两点:

  • 构造函数用于创建某一类对象,其首字母要大写

  • 构造函数要和new一起使用才有意义

<script>
//1.利用new Object()创建对象
var obj1 = new Object();
//2.利用对象字面量创建对象
var obj2 = {};
//3.利用构造函数创建对象
function Star(uname,age){
this.uname = uname;
this.age = age;
this.sing = function(){
console.log('sing');
}
}
var ldh = new Star('刘德华',20);
console.log(ldh);
ldh.sing();
</script>

2.构造函数中的一些成员

JavaScript的构造函数中可以添加一些成员,可以在构造函数本身上添加,也可以在构造函数内部的this上添加。通过这两种方式添加的成员,就分别称为静态成员和实例成员。

  • 静态成员:在构造函数本身上添加的成员称为静态成员,只能由构造函数本身来访问

  • 实例成员:在构造函数内部创建的对象成员称为实例成员,只能由实例化的对象来访问

<script>
//构造函数中的属性和方法我们称为成员,成员可以添加
function Star(uname,age){
this.uname = uname;
this.age = age;
this.sing = function(){
console.log('sing');
}
}
var ldh = new Star('刘德华',18);
//1.实例成员就是构造函数内部通过this添加的成员 uname age sing 就是实例成员
//实例成员只能通过实例化的对象来访问
console.log(ldh.uname);
console.log(Star.uname);//不可以通过构造函数来访问实例成员
//2.静态成员 在构造函数本身上添加的成员 sex就是静态成员
Star.sex = '男';
//静态成员只能通过构造函数来访问
console.log(Star.sex);
console.log(ldh.sex);//不能通过对象来访问
</script>

3. 构造函数和原型

3.1构造函数的问题

会存在浪费内存的问题

3.2 构造函数原型 prototype

构造函数通过原型分配的函数是所有对象所共享的。

  • JavaScript规定,每一个构造函数都有一个prototype属性,指向另一个对象。

  • 注意这个prototype就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有。

  • 我们可以把那些不变的方法,直接定义在prototype对象上,这样所有对象的实例就可以共享这些方法

<script>
function Star(uname,age){
this.uname = uname;
this.age = age;
}
Star.prototype.sing = function(){
console.log('我会唱歌');
}
var ldh = new Star('刘德华',18);
var zxy = new Star('张学友',19);
ldh.sing();
console.log(ldh); //对象身上系统自动添加一个_proto_指向我们构造函数的原型对象prototype
console.log(ldh._proto_ === Star.prototype);
//方法的查找规则:首先看ldh对象身上是否有sing方法,如果有就执行这个对象上的sing
//如果没有sing这个方法,因为有_proto_的存在,就去构造函数原型对象prototype身上去查找sing这个方法
</script>

对象都会有一个属性_ proto_ 指向构造函数的 prototype原型对象,之所以我们对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有_ proto_ 原型的存在。

3.3 constructor 构造函数

  • 对象原型(_ proto_ ) 和构造函数( prototype )原型对象里面都有一个属性constructor属性,

  • constructor我们称为构造函数,因为它指回构造函数本身。

Star.prototype = {
constructor:Star,//利用constructor 属性指回原来的构造函数
sing:function(){
console.log('我会唱歌');
},
movie:function(){
console.log('我会演电影');
}
}
var ldh = new Star('刘德华',18);
var zxy = new Star('张学友',19);
console.log(Star.prototype);
console.log(ldh._proto_);
console.log(Star.prototype.constructor);
console.log(ldh._proto_.constructor);

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

3.5 原型链

posted @   准备开始  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示