学习JavaScript(3)创建类


前言

学习JavaScript(1)关于对象

参考红宝书JavaScript高级程序设计第三版第六章

虽然object构造函数或对象的字面量都可以用来创建单个对象,但这些方法有个明显的缺点:使用同一个接口创建很多对象,会产生大量的重复代码,为解决这个问题,有以下几种常用方式创建对象

一.工厂模式

一种函数,使用它来封装以特定接口创建对象的细节

function cat(name,year,color){
    let cat = new Object();
    cat.name = name;
    cat.year = year;
    cat.color = color;
    cat.introduction = function(){
        return this.name + " is a " + this.year + " years old " + this.color + " cat";
    }

    return cat;
}

let cat1 = cat("vivi",1,"black");
console.log(cat1.introduction());
//vivi is a 1 years old black cat

let cat2 = cat("cici",12,"white");
console.log(cat2.introduction());
//cici is a 12 years old white cat

可以无数次调用这个函数,而每次它都会返回三个属性和一个方法的对象。

然而就有一个新的问题:
cat1和cat2的对象类型是否相同?
工厂模式无法判断

二.构造函数模式

要创建cat的新实例,必须使用new操作符。以这种方式调用构造函数经历以下四个步骤:
1)创建一个新对象
2)将构造函数的作用域赋给新对象(this指向新对象)
3)执行构造函数中的代码(新对象添加属性)
4)返回新对象

注意!按照惯例,构造函数始终都应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头

function Cat(name,year,color){
    this.name = name;
    this.year = year;
    this.color = color;
    this.introduction = function(){
        return this.name + " is a " + this.year + " years old " + this.color + " cat";
    }
}

let cat1 =new Cat("vivi",1,"black");
console.log(cat1.introduction());
let cat2 =new Cat("cici",12,"white");
console.log(cat2.introduction());

之所以称之为构造函数,是因为这创建的对象都有一个constructor(构造函数)属性,在这一点上我们就可以得到对象的类型,从而判断是否为相同对象。

console.log(cat1.constructor)
//这里返回的是整个对象的定义
console.log(cat1.constructor == Cat)
//true
console.log(cat1.constructor == cat2.constructor)
//true

然而我们发现构造函数也有一个缺点,以构造函数方式创建函数,会导致不同的作用域链和标识符解析,但创建Function新实例的机制仍然是相同的。因此,不同实例上的同名函数是不相等的

console.log(cat1.introduction == cat2.introduction)
//false

三.原型模式

我们创建的每个函数都有prototype(原型)属性,这个属性是一个指针,指向一个对象。prototype就是通过调用构造函数而创建的哪个对象实例的原型对象

原型对象的好处是,不必在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中

function Cat(){
}

Cat.prototype.name = "kiki";
Cat.prototype.year = 1;
Cat.prototype.color = "black";
Cat.prototype.introduction = function(){
     return this.name + " is a " + this.year + " years old " + this.color + " cat";
}

let cat1 = new Cat();
console.log(cat1.introduction());
//kiki is a 1 years old black cat
let cat2 = new Cat();
cat2.name = "cici";
console.log(cat2.introduction());
//cici is a 1 years old black cat

在原型模式创建时,不同实例上的同名函数相等

console.log(cat1.introduction == cat2.introduction);
//true

四.组合使用构造函数模式和原型模式(常用)

创建自定义类型的最常见方式,就是组合使用构造函数模式与原型模式。构造函数模式用于定义实例属性,而原型模式用于定义方法和共享属性

function Cat(name,year,color){
    this.name = name;
    this.year = year;
    this.color = color;
}

Cat.prototype = {
    constructor: Cat,
    introduction : function(){
        return this.name + " is a " + this.year + " years old " + this.color + " cat";
    }
}

let cat1 =new Cat("vivi",1,"black");
console.log(cat1.introduction());
//vivi is a 1 years old black cat
let cat2 =new Cat("cici",12,"white");
console.log(cat2.introduction());
//cici is a 12 years old white cat
console.log(cat1.name == cat2.name);
//false
console.log(cat1.introduction == cat2.introduction);
//true

组合使用构造函数模式和原型模式是目前在ECMAScript中使用最广泛、认同度最高的一种创建自定义类型的方法,是定义引用类型的一种默认模式


总结

个人学习笔记总结,每天进步多一点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值