抽取对象共用的属性和行为封装成类
对象:在JavaScript中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象(属性+方法)
类:泛指某一大类(class)
对象:通过实例化的一个具体对象
constructor构造函数
constructor()方法是类的构造函数(默认方法),用于传递参数,返回实例对象,通过new命令生成对象实例时,自动调用该方法
<script>
class Father{
constructor(x,y){
this.x=x;
this.y=y;
}
info(){
console.log(this.x+this.y);
}
}
var y=new Father(2,4);
y.info(); //6
</script>
继承(extends)
子类可以继承父类的一些属性和方法
super关键字
super关键字用于访问和调用对象父类上的函数。可以调用父类的构造方法,也可以调用父类的普通函数
注意:子类在构造函数中使用super,必须放到this前面(必须先调用父类的构造方法,再使用子类的构造方法)
1.在ES6中,先定义类,才能通过类实例化对象
2.类里面的共有的属性和方法一定要加this使用
子类继承父类的构造方法
<script>
class Father{
constructor(x,y){
this.x=x;
this.y=y;
}
info(){
console.log(this.x+this.y).
}
}
class Son extends Father{
}
var e = new Son(2,4);
e.info();
</script>
<script>
class Father{
constructor(x,y){
this.x=x;
this.y=y;
}
info(){
console.log(this.x+this.y);
}
}
class Son extends Father{
constructor(x,y){
//倘若子类已有构造函数,要想使用父类的方法,需使用super()
super(x,y);
}
}
var e = new Son(2,4);
e.info();
</script>
子类继承父类的普通方法
<script>
class Father{
money(){
return '年薪百万';
}
}
class Son extends Father{
money(){
//继承父类中money()的普通方法
console.log(super.money()+'我也可以');
}
}
var t = new Son();
t.money();
</script>
综合
class Father{
constructor(name){
this.name=name;
// this.age=age;
}
info(){
return this.name+'今年';
}
}
class Son extends Father{
constructor(name,age){
super(name);
// this.name=name;
this.age=age;
}
info(){
console.log(super.info()+this.age+'了');
}b
}
var d = new Son('wzm',22);
d.info(); //wzm今年22
——————————————————
在ES6之前,对象不是基于类创建的,而是用一种构造函数的特殊函数来定义对象和他们的特征
构造函数是一种特殊的函数,用来初始化对象,即为对象成员变量赋初始值,它总与new 一起使用
在js中,使用构造函数要注意:
1.构造函数用于创建某一类对象,其首字母要大写
2.构造函数要和new 一起使用才有意义
new 在执行时会做四件事
1.在内存中创建一个新的空对象
2.让this指向这个新对象
3.执行构造函数里面的代码,给这个新对象添加属性和方法
4.返回这个新对象(因此构造函数里面不需要return)
实例成员只能通过实例化对象访问
静态成员只能通过构造函数访问
function Start(name,age){
this.name=name;
this.age=age;
this.skill=function(){
console.log('敲代码')
}
}
var g=new Start('wzm',22);
//动态
console.log(g.name); //wzm
console.log(g.age); //22
g.skill();
//静态
Start.sex='男';
console.log(Start.sex) //男
console.log(g.sex) //undefined
构造函数在创建对象时存在内存浪费的问题(主要是公共方法引起的)
创建一个对象就会占用一个内存地址,因此同一构造函数创建的对象,它们不相等
构造函数原型prototype
构造函数通过原型分配的函数是所有对象所共享的
JavaScript规定,每一个构造函数都有一个prototype属性,指向另一个对象。(这个prototype就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有)
一般情况,公共属性定义到构造函数里面,公共方法放到原型对象上
Start.prototype.skill=function(){
//解决了内存浪费
console.log('敲代码');
}
<script>
function Start(name,age){
this.name=name;
this.age=age;
// this.skill=function(){
// console.log('敲代码')
// }
console.log(this.name+'今年'+this.age+'了');
}
Start.prototype.skill=function(){
//解决了内存浪费
console.log('敲代码');
}
var g=new Start('wzm',22);
var y=new Start('lzy',18);
//验证是否占用空间
console.log(g.skill === y.skill)
</script>
原型:一个对象,成为prototype为原型对象
原型的作用:共享方法
对象原型_proto_
对象都会有一个属性_proto_指向构造函数的prototype原型对象,对象能是用构造函数prototype原型对象的属性和方法,就是因为对象有_proto_原型的存在
对象._proto===构造函数._prototype_ //true
1.只要是对象就有_proto_原型,指向原型对象
2.我们Start原型对象里面的_proto_原型指向的是Object
Start._prototype_._proto_ === Object._prototype_ //true
Object._prototype_._proto_=null
Start是一个构造函数,有prototype,而prototype是一个对象,是对象就有_proto_原型,指向原型对象
原型链
对象._proto===构造函数._prototype_
构造函数._prototype_._proto_ === Object._prototype_
扩展内置对象
作用:解决构造函数原型对象中没有的方法
数组求和∑
//方法一
Array.prototype.sum=function (){
var sum=0;
for(var i=0;i<this.length;i++){
sum+=this[i];
}
return sum;
}
//写法二
Array.prototype={
sum:function {
var sum=0;
for(var i=0;i<this.length;i++){
sum+=this[i];
}
return sum;}}
var arr=[1,2,3];
console.log(arr.sum()) //6
注意:方法二行不通,原因会覆盖构造函数原型对象的方法
Call方法
作用:
1.call()可以调用函数
2.call()可以改变这个函数的this指向,此时函数就指向处理的对象
function fn(){
console.log(11)
console.log(this) //Windows对象
}
var y={
name:'wzm'};
fn.call(); //11
fn.call(y) //将fn中的this指向y对象
<script>
function Father (uname,age){
this.uname=uname;
this.age=age;
}
function Son(uname,age){
Father.call(this,uname,age);
//将Father中的this指向Son
}
var son=new Son('wzm',22);
console.log(son);
</script>
拓展
改变this指向的其他两种( apply () , bind () )
apply ()
var t ={
name:'wzm'
}
function fn(arr){
console.log(arr);
}
fn.apply(t,['lzy']);
//注意:传递的参数必须是数组(伪数组)
案例<求数组中最大的值>
var f=[];
var max=Math.max.apply(Math,f);
console.log(max);
bind()
fun.bind(被指向函数,参数)
注意:参数不一定是数组;
返回由指定的this值和初始化参数改造的原函数拷贝
var o={
name:'wzm';
}
function fn(a,b){
console.log(a+b);
}
var f =fn.bind(o) //{name:'wzm'}
var f=fn.bind(o,1,2) //{name:'wzm'},3
f();
Es6之前,使用构造函数和原型实现面向对象编程
Es6之后,使用类实现面向对象编程