当前位置:网站首页>ES类和对象、原型

ES类和对象、原型

2022-07-07 07:20:00 小白啥时候能进阶成功

一、“前端开发”名称的由来

Web1.0时代的网页制作:网页主要是静态页面,无法和服务器进行交互。网站开发工具(网页三剑客)DreamWeaverFireWorksFlash

  • Web2.0时代的前端开发:现在的页面开发,无法从开发维度还是开发方式上,更接近传统的网站后台开发,因此不再叫做“页面制作”,而是“前端开发”。新三剑客:HTMLCSSJavaScript
  • HTML:超文本标记语言,是一门描述性语言
  • CSS:层叠样式表,是用来控制网页外观的一种技术。
  • JavaScript:即JS,是一种嵌入到 HTML页面中的脚本语言,由浏览器一边解释一边执行

HTML用于控制网页的结构,CSS用于控制网页的外观,而JavaScript控制着网页的行为。

 二、ES的类和对象

1、Class关键字;

2、constructor构造函数;

3、方法前不需要function关键字;

4、方法之间不需要逗号

5、extends继承和super()关键字:extends表示继承(C中的public)

<script type="text/javascript">
    class Father{
        constructor(x,y)
        {
            this.x = x;
            this.y =y;
        }
        sum()
        {
            console.log("father's sum:"+(this.x+this.y));
        }
        song()
        {
            console.log("father is sing qinghuaci");
        }
    }
    class Son extends Father{
        constructor(x,y)
        {
            super(x,y);  //调用了父类中的构造函数
        }
        
    }

    var son1 = new Son(3,4);
    son1.sum();
    son1.song();     
</script>

6、super关键字: 在子类的构造器中,通过调用super(),则向父类的构造函数中传递参数。

class Son extends Father{
    constructor(x,y)
    {
        super(x,y);  //1、调用了父类中的构造函数,赋值给父类的this对象
    }
}

7、super关键字:通过使用“super.属性”或“super.方法”的方式,显示调用父类中声明的属性和方法。

class Son extends Father{

    song()
    {
        console.log("son is sing qinghuaci");//2、子类的song方法
        super.song();//3、调用父类的song方法
    }
        
}

子类调用方法时,先遍历子类是否有该函数,如果有,则执行子类的函数。如果没有,则遍历父类,执行父类的函数。

8、super必须放在子类的this前面

class Son extends Father{
    constructor(x,y)
    {
        super(x,y);  //1、调用了父类中的构造函数,赋值给父类的this对象
        this.x = x;  //2、将x,y传递给自己的this对象
        this.y = y;
    }
}

9、this的指向问题

(1)constructor里面的this指向的是创建的实例对象;

(2)方法中的this指向的是调用者;例如:下面的例子中,sum方法中的this指向的是这个按钮,因为按钮调用了这个方法。

<!DOCTYPE html>
<html>
<head>
<title>CanvasTest</title>
<meta charset="UTF-8">
<div class="items">
    <button>Play</button>
</div>
</head>
<body>
    <script type="text/javascript">
    class Father{
        constructor(x,y)
        {
            this.x = x;
            this.y =y;
            this.btn = document.querySelector("button");
            this.btn.onclick = this.sum;
        }
        sum()
        {
            //这个sum方法中的this指向的是这个按钮,因为这个按钮调用了sum函数
            console.log(this);
            console.log("father's sum:"+(this.x+this.y));
        }
    }
    var f = new Father(2,5);
    </script>
</body>
</html>

三、构造函数和原型

1、不同对象的方法会重复申请内存进行创建

function Star(){
    this.name = uname;
    this.age = age;
    this.sing=function()
    {
        console.log("sing song");
    }        
}
var ldh = new Star("刘德华");
var zxy = new Star("张学友");

ldh.sing();
zxy.sing();
console.log(ldh.sing() ==== zxy.sing());//false,是两个函数

ldh和zxy的song方法分别在两个地址。

2、构造函数原型

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

构造函数通过原型分配的函数是所有对象所共享的。可以把那些不变的方法,直接定义在prototype对象上,这样所有对象的实例就可以共享这些方法。

function Star(uname,age){
    this.name = uname;  
    this.age = age;      
}
//song放到了构造函数的原型对象里面了。
Star.prototype.sing = function()
{
    console.log("sing song");

}
var ldh = new Star("liudehua");
var zxy = new Star("张学友");

ldh.sing();//在构造函数的原型对象上找到song方法
zxy.sing();

一般情况下,我们的公共属性定义到构造函数里面,公共方法我们放到原型对象身上。

3、对象原型 __proto__

实例化后的对象系统自动添加一个属性:__proto__他指向构造函数的原型对象prototype

对象的属性__proto__和构造函数的原型对象prototype等价

function Star(uname,age){
    this.name = uname;  
    this.age = age;      
}
Star.prototype.song = function()
{
	console.log("sing song");

}
var ldh = new Star("liudehua");
var zxy = new Star("张学友");

console.log(ldh.__proto__ === Star.prototype);//true;

ldh.sing();

查找规则:首先看ldh对象身上是否有sing方法,如果有,执行对象的sing方法。如果没有,去构造函数原型对象身上查找。

4、constructor函数

对象原型(__proto__)和构造函数原型对象(prototype)里面都有一个constructor属性;constructor我们称为构造函数,因为它指回构造函数本身。

作用一:constructor主要用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数。

function Star(uname,age){
    this.name = uname;
    this.age = age;
}
// 把原型对象赋值成一个新的对象
Star.prototype.sing(){
    console.log("sing song");
}
var ldh = new Star("liudehua");
var zxy = new Star("张学友");

console.log(ldh.__proto__.constructor);
console.log(Star.prototype.constructor);

运行结果:

作用二:很多情况下,我们需要手动地利用constructor这个属性指回原来的构造函数。

function Star(uname,age){
	this.name = uname;
	this.age = age;
}
// 把原型对象赋值成一个新的对象
Star.prototype = {
	sing:function(){
		console.log("sing song");
	},
	movie:function(){

	}
}
var ldh = new Star("liudehua");
var zxy = new Star("张学友");

console.log(ldh.__proto__.constructor);
console.log(Star.prototype.constructor);

 结果:

 原型对象的constructor指向的不是Star,是因为Star的原型对象被覆盖了,因此原型对象中的constructor不再指向Star.

解决方法:

function Star(uname,age){
	this.name = uname;
	this.age = age;
}
// 把原型对象赋值成一个新的对象
Star.prototype = {
    constructor:Star,//指回原先的构造函数
	sing:function(){
		console.log("sing song");
	},
	movie:function(){

	}
}
var ldh = new Star("liudehua");
var zxy = new Star("张学友");

console.log(ldh.__proto__.constructor);
console.log(Star.prototype.constructor);

结果:

总结:如果修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动地利用constructor指回原来的构造。

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

原网站

版权声明
本文为[小白啥时候能进阶成功]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_34754747/article/details/125483944