JS构造函数与原型

原文链接:http://blog.csdn.net/kkdelta/article/details/8456879

 

JavaScript中定义"类"的时候可以通过构造函数和原型的方式来实现,它们之间有何区别和利弊呢?

首先来看一个通过构造函数实现类定义的例子:

function Car(color,model,drivers){
	this.color=color;
	this.model=model;
	this.drivers=drivers;
	
	this.blar = function(){
		alert("I am a car: " + model + " in " + color + ". " + drivers + " can drive me" );
	}
}

var car1 = new Car('red','BMW',['Mike','Kevin']);
car1.blar();

var car2 = new Car('red','BMW',['Mike','Kevin']);
car2.blar();

 

在上面的例子中,每一个实例中,函数blar都会拷贝到实例中,弊端就是浪费内存。
在来看一个通过利用prototype来定义类的例子:

function Drivers(){
    var names="";
    this.addDriver= function(name){
        names = names +" " + name;
    }
    this.toString = function(){
        return  names;
    }
}


function Car(){
}

Car.prototype.color = "red";
Car.prototype.model = "BMW";

//Car.prototype.drivers = ['Mike','Kevin'];

Car.prototype.drivers =new Drivers();

Car.prototype.blar = function(){
        alert("I am a car: " + this.model + " in " + this.color + ". " + this.drivers + " can drive me" );
    };

var car1 = new Car();
car1.color='Blue';
//car1.drivers.push('Luios');
car1.drivers.addDriver('Mike');
car1.drivers.addDriver('Kevin');
car1.drivers.addDriver('Luios');

car1.blar();//outputs I am a car: BMW in Blue. Mike,Kevin,Luios can drive me
var car2 = new Car();
car2.blar(); //outputs I am a car: BMW in red. Mike,Kevin,Luios can drive me

 prototype方式定义的方式,函数不会拷贝到每一个实例中,所有的实例共享prototype中的定义,节省了内存。但是属性如果是对象的话,所有实例也是共享同一个对象,

如上例中的drivers使用自定义对象或者数组的时候,如果其中某一个实例改变了其中的值,所有的实例的值都被改变。因为所有实例的属性指向的是同一个对象的引用,如果上面的例子中car2.drivers=['Ivy','Lili'];来改变实例car2的属性内容,相对于car2.drivers指向了另一个对象(这时候car2有一个实例属性,有一个prototype属性都是drivers)。
Javascript是一种动态语言,实例创建之后可以动态添加属性和方法,在“构造函数”的定义之外也可以添加属性和方法。其实,下面例子中sayHi本身也是一个全局的类型为Function的实例。

 

 

var obj = {};
obj.prop="value";
obj.test = function(){
	alert("test function: " + this.prop);
}
obj.test();

function sayHi() {
	alert("hi");
}

sayHi.sayHello = function() {
	alert("hello");
};
sayHi.sayHello();//outputs hello

 注意如果想让添加的属性或者方法能够被实例使用,要使用prototype添加,下面的例子说明了这一点

function sayHi() {
	alert("hi");
}

sayHi.sayHello = function() {
	alert("hello");
};

sayHi.sayHello();//outputs hello

var osayHi = new sayHi();//outputs hi
osayHi.sayHello(); // TypeError: osayHi.sayHello is not a function

 因为不是通过在prototype中以这样的方式添加的(sayHi.prototype.sayHello),实例是不能访问sayHello方法的,只能通过sayHi.sayHello(类似如静态方法)的方式访问。同样如果添加的时候是通过prototype方式,则不能用静态方式访问。 

function sayHi() {
	alert("hi");
}

sayHi.prototype.sayHello = function() {
	alert("hello");
};

var osayHi = new sayHi();// outputs hi
osayHi.sayHello(); // outputs hello

sayHi.sayHello(); //TypeError: sayHi.sayHello is not a function

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值