类、原型与原型链

面向对象、过程编程

面向过程编程:按照步骤一步一步执行,性能比面向对象高
面向对象编程:把事务分解成一个一个对象,发现对象有哪些功能,然后由对象分工合作完成。代码灵活,可复用性。
面向对象特征:封装性、继承性、多态性

ES6中类和对象

1)类:抽象对象的公共部分,泛指某一大类
抽取(抽象)对象共用的属性和行为封装成一个类(模板)
2)对象:
对象是一个具体的事物,在javascript中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象。
对象由属性和方法组成。
对类进行实例化,获取类的对象

es6创建类

语法:

class name{}
//创建实例:
var xx=new name();

注意:类必须用new实例化对象

// 创建明星类
class star{
	constructor(uname){
		this.uname=uname
	}
}
//实例
var ldh=new star('刘德华')
console.log(ldh.uname)
//类constructor构造函数
constructor方法是类的构造方法,用于传递参数返回实例对象,
通过new命令生成对象实例时,自动调用该方法。
如果没有显式定义会自动给我们创建一个constructor()

es6类中添加方法

直接在类中添加即可

// An highlighted block
class star{
	constructor(uname){
		this.uname=uname
	}
	sing(){
		console.log("我唱歌")
	}
}

es6类的继承

子类继承父类的一些属性和方法 extends

class Father{
	constructor(){}
	money(){
		console.log(" 爸爸的钱")
	}
}
class Son extends Father{
}
var son=new Son()
son.money()

super关键字

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()

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

// An highlighted block
class Father{
	say(){
		console.log("爸爸说")
	}
}
class Son extends Father{
	say(){
		console.log("儿子说")
		console.log(super.say())
	}
}
var son=new Son()
son.say()

es6子类继承父类方法

子类继承父类加法,扩展减法

// An highlighted block
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)
		this.x=x;
		this.y=y;
	}
	substrct(){
		console.log(this.x-this.y)
	}
}
var son=new son(1,2)
son.sum()
son.substrct()

es6中类和对象注意点

1) es6中没有变量提升,所以必须先定义类,才能通过类实例化对象
2)类里边共有的属性和方法一定要加this使用
3)类中this指向

<script>
	var that;
	class Star{
		constructor(uname,age){
			this.uname=name;
			this.age=age
			this.btn=document.querySelector('button');
			this.btn.onclick=this.sing
		}
		sing(){
			//this中指向的是btn这个按钮,因为这个按钮调用了这个函数
			console.log(this)
			console.log(that.uname)
		}
	}
   var ldn=new Star("刘德华",12)
 
</script>

构造函数和原型

1)构造函数创建对象
2)原型作用
3)访问对象成员规则

构造函数

es6之前,对象基于构造函数创建
创建对象通过以下三种方式:
1)对象字面量
2)new Object()
3)自定义构造函数

<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("唱歌")
		}
	}
	var ldh=new Star("ldh",18)
	ldh.sing()
</script>

构造函数是一种特殊的函数,主要用来初始化对象,它与new一起使用。
new在执行过程中会做四件事:
1)内存中创建一个空对象
2)让this指向这个空对象
3)执行构造函数里边的代码,给这个新对象添加属性和方法
4) 返回这个对象

// 构造函数中的属性和方法我们称为成员,成员可以添加
function Star(uname,age){
	this.uname=uname
	this.age=age
	this.sing=function(){
		console.log("唱歌")
	}
}
var ldh=new Star('刘德华',18);
//实例成员就是构造函数内部通过this添加的成员,uname,age,sing就是实例成员
//实例成员只能通过实例化的对象来访问

//2.静态成员 在构造函数本身删添加的成员
例如:Star.sex='男'

原型

构造函数存在浪费空间的情况
在这里插入图片描述

function Star(uname,age){
	this.uname=uname
	this.age=age
	this.sing=function(){
		console.log("唱歌")
	}
}
Star.prototype.sing=funciton(){console.log("唱歌")}
var ldh=new Star('刘德华',18)
var zxy=new Star('zhangxuyo',19)
ldh.sing!==zxy.sing

构造函数原型prototype(原型对象)

构造函数通过原型分配的函数是所有对象所共享的
javascript规定每一个构造函数都有一个prototype属性,指向另一个对象,这个prototype就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有。

问答:
1.原型是什么?
原型是一个对象,我们称prototype为原型对象
2.原型的主要作用?
共享方法

构造函数是一种特殊的方法,主要用来创建对象时初始化对象。每个构造函数都有prototype(原型)属性,每个函数都有prototype(原型)属性,这个属性是一个指针,指向一个对象,这个对象的用途是包含特定类型的所有实例共享的属性和方法,即这个原型对象是用来实例共享属性和方法的。而每个实例内部都一个指向原型对象的指针。

对象原型 proto

对象都会有一个__proto__指向构造函数的prototype原型对象,之所以我们对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有__proto__原型的存在。
__proto__对象原型和原型对象prototype是等价的
在这里插入图片描述

constructor构造函数

对象原型(proto)和构造函数(prototy)原型对象 里边都有一个属性constructor属性,constructor我们称为构造函数,因为他指回构造函数本身。
在这里插入图片描述

function Star(uname,age){
	this.uname=uname;
	this.age=age
}
Star.prototype.sing=function(){
	console.log('我会唱歌')
}
Star.prototype.movie=function(){
	console.log('我会电影')
}

var ldh=new Star('刘德华',18)
var zxy=new Star('张学友'19)
console.log(Star.prototype.constructor);
console.log(ldh.__proto__.constructor)

//指回原来的构造函数
Star.prototype={
//如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用
//constructor指回原来的构造函数
	constructor:Star,
	sing:function(){}
	movie:function(){}
}

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

在这里插入图片描述

原型链

创建一个Array对象var arr=[1,2,3],其原型链是:
arr----->Array.prototype---->Object.prototype------>null
Array.prototype定义了indexOf()、shift()等方法,因此你可以在鄋Array对象上直接调用这些方法。
创建一个函数时:
function foo(){ return 0;}
函数也是一个对象:原型链是:
foo---->Function.prototype---------->Object.prototype------->null

js的成员查找机制

1)当访问一个对象的属性(包括方法)时,首先查找这个对象有没有该属性
2)如果没有就查找它的原型(也就是__proto__指向的prototype原型对象)
3)如果还没有就查找原型对象的原型(Object的原型对象)
4)依次类推一直找到Object位置(null)

继承 终于搞明白了哈哈哈哈

es6之前并没有提供extends继承,我们可以通过构造函数+原型对象模拟实现继承,被称为组合继承。
1)call 调用这个函数,修改函数运行时的this指向
fun.call(thisArg,arg1,arg2)

借用构造函数继承父类型属性

核心原理:通过call()把父类型的this指向子类型的this,这样就可以实现子类型继承父类型的属性。

//借用父构造函数继承属性
//1.父构造函数
function Father(uname,age){
	//this指向父构造函数的对象实例
	this.uname=uname;
	this.age=age;
}
//2.子构造函数
function Son(uname,age){
	//this指向子构造函数的对象实例
	//调用父构造函数,将父构造函数的this改为子构造函数的this
	Father.call(this,uname,age)
}
var son=new Son('ldh',18)
console.log(son)

相当于给子构造函数的this对象添加了uname和age属性。
在这里插入图片描述

借用原型对象继承父类型方法


function Father(uname,age){
	this.uname=uname;
	this.age=age
}
Father.prototype.money=function(){
	console.log(100000000)
}
function Son(uname,age){
	Father.call(this,uname,age)
}
//Son.prototype=Father.prototype //图一 这样赋值会有问题,如果直接修改了子原型对象,父原型对象也会一起变化
Son.prototype=new Father(); //实例化父构造函数 图二:
//如果利用对象的形式修改了原型对象,别忘了利用constructor指向原来的构造函数
Son.prototype.constructor=Son;
//这个是子构造函数专门的方法
Son.prototype.exam=function(){
	console.log('孩子要考试')
}
var son=new Son('刘德华',18);
console.log(son);
console.log(Father.prototype);
console.log(Son.prototype.constructor)

图一:
在这里插入图片描述
图二:
在这里插入图片描述

共有的方法,写到原型对象上

原型对象this指向

<script>
	function Star(uname,age){
		this.uname=uname;
		this.age=age;
	}
	Star.prototype.sing=function(){
		console.log('我会唱歌')
	}
	var ldh=new Star('刘德华',18)
	//在构造函数中,里面this指向的是对象ldh
</script>

在这里插入图片描述

es5中的新增方法

数组方法

迭代遍历方法:forEach()、map()、filter()、some()、every()

array.forEach(function(currentValue,index,arr))
currentValue:数组当前项的值
index:数组当前项的索引
arr:数组对象本身

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微星星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值