原文链接: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
相关推荐
JavaScript构造函数和原型对象介绍,对于构造函数的创建以及一些简单地介绍,还有就是原型对象对于构造函数的一些补充。
下面小编就为大家带来一篇JS构造函数与原型prototype的区别介绍。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
深入浅出的讲解JavaScript中最难理解的Js构造函数、原型链、Ajax三大部分
构造函数、函数原型、函数实例三者之间的关系!详细的后续补上
javascript中构造函数以及原型的基础知识梳理
构造函数和原型构造函数构造函数通过原型分配的函数是所有对象所共享的JS规定,每一个构造函数都有一个 prototype 属性,指向另一个对象,注意这个proto
在本篇文章里小编给大家分享了关于JavaScript中构造函数与原型链之间的关系相关知识点,需要的朋友们学习下。
以下是一个构造函数的例子 如果是实例方法,不同的实例化,它们引用的地址是不一样的,是唯一的。 //定义一个构造函数 function People(name,age){ this.name=name; this.age=age; this.dothings=function(){ ...
构造函数、原型实现继承的缺陷 首先来分析构造函数和原型链两种实现继承方式的缺陷: 构造函数(对象冒充)的主要问题是必须使用构造函数方式,且无法继承通过原型定义的方法,这不是最好的选择。不过如果使用原型链...
对象,是javascript中非常重要的一个梗,是否能透彻的理解它直接关系到你对整个javascript体系的基础理解,说白了,javascript就是一群对象在搅。。(哔!)。
主要介绍了js构造函数constructor和原型prototype原理与用法,结合实例形式分析js构造函数constructor和原型prototype基本原理、功能、使用方法及操作注意事项,需要的朋友可以参考下
本文实例讲述了JavaScript原型对象、构造函数和实例对象功能与用法。分享给大家供大家参考,具体如下: 大家都知道,javascript中其实并没有类的概念。但是,用构造函数跟原型对象却可以模拟类的实现。在这里,就先...
[removed] /* * 组合模式: 构造函数模式+原型模式 这种方式是javascript中最通用的创建对象的方式 变量类型属性:用构造函数传递 函数类型属性:用原型模式声明 */ function Student(name,age){ this.name=name;...
证明你对JavaScript面向对象已经有一定的了解,如还有什么不理解的可以参考《面向对象JS基础讲解,工厂模式、构造函数模式、原型模式、混合模式、动态原型模式》,接下来讲一般通过那些方法完成JavaScript的继承。...
主要介绍了javascript组合使用构造函数模式和原型模式的方法,通过一个简单实例分析了javascript构造函数模式与原型模式的使用方法,需要的朋友可以参考下
构造函数 原型对象 实例、图解
js播放列表一个Treehouse项目,使用JavaScript构造函数和原型。 在这个包装了Treehouse的“面向对象编程”标志的项目中,我的任务是向所提供的文件中添加功能,以使用JavaScript创建一个简单的(不起作用的)媒体...
javascript组合使用构造函数模式和原型模式实例.docx