浅析JavaScript原型

原型

原型,字面解释,原始的类型或模型,即它是一个最初的模板或框架,我们可以在它的基础上进行个性化修改。在JavaScript中同样适用。

1.原型模式VS构造函数

我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个对象,即通过调用构造函数而创建的那个对象的原型对象。类似于我们经常用的继承,它包含可以由特定类型的所有实例共享的属性和方法。

接下来结合构造函数对比的方式进行总结介绍。

1.1定义对象信息

构造函数

function Box(name,age){
	this.name='wang'; //实例属性
this.age=23; //实例属性
this.run=function(){ //实例方法
return this.name+this.age+'fighting...';
	}
}

原型模式

与构造函数不同,不必在构造函数中定义对象信息,可以直接将这些信息添加到原型中

function Box1(){} //构造函数函数体内什么都没有
Box1.prototype.name='wang'; //原型属性
Box1.prototype.age=23; //原型属性
Box1.prototype.run=function(){ //原型方法
return this.name+this.age+'fighting...';
} 

1.2资源共享

构造函数

不同的实例化,得到的方法地址是不一样的,是唯一的。

var box1=new Box('Lee’,100);
var box2=new Box('Jack',200);

代码执行原理图(一)

原型模式

可以让所有对象实例共享它所包含的属性和方法,而且他们的地址是共享的,都一样。

var box1=new Box1()
var box2=new Box1()

代码执行原理图(二)

1.3执行流程

构造函数

只有实例对象,所以不存在先后顺序

原型模式

优先访问实例对象上的属性,如果对象上没有再去访问原型对象上的属性。虽然我们可以通过对象实例访问保存在原型中的值,但却不能通过对象实例重写原型中的值

var box1=new Box1();
//alert(box1.name); //wang,原型中的属性
box1.name=’zhang’;
Alert(box1.name); //zhang,就近原则,先访问实例对象的属性,值为’zhang’ 

var box2=new Box1();
Alert(box2.name); //wang,对象实例的属性不能被共享,box2只能访问原型中的属性

2.优缺点

2.1优缺点

原型的共享性是它的优点同时也是它的缺点。共享对于函数和包含基本值的属性是可以的,如果属性包含引用类型,就会存在一定的问题:每次实例化出的数据需要保留自己的特性,而不能共享,但是引用类型的属性的修改会同步到原型,这致使很多开发者放弃使用原型。

function Box1(){}
Box.prototype={
	name:wang'; //原型属性
age:23; //原型属性
family:['爸爸','妈妈','哥哥']; //添加了一个数组属性,这属于引用类型
run:function(){ //原型方法
return this.name+this.age+this.family;
}
};
var box1=new Box1();
box1.family.push('姐姐'); //在实例中添加‘姐姐’
alert(box1.run()); //wang23爸爸妈妈哥哥姐姐
var box2=new Box1();
alert(box2.run()); //wang23爸爸妈妈哥哥姐姐,也有‘姐姐’了。

2.2解决方案

为了解决构造传参和共享问题,组合构造函数+原型模式:共有属性在构造函数中定义,共有方法在原型中定义。

function Box1(name,age){ //不共享的使用构造函数
this.name=name;
	this.age=age;
	this.family=['爸爸','妈妈','哥哥'];
};

Box.prototype={ //共享的使用原型模式
constructor:Box,
 run:function(){ //原型方法
return this.name+this.age+this.family;
}
};

改进1

可以将原型封装到构造函数中,提高代码可读性

function Box1(name,age){ //不共享的使用构造函数
this.name=name;
	this.age=age;
	this.family=['爸爸','妈妈','哥哥'];

Box.prototype. run=function(){ //原型方法
return this.name+this.age+this.family;
 }
};
var box1=new Box1('Lee',100);
alert(box1.run());
var box2=new Box1('Jack',200);
alert(box2.run()); 

注意:原型被初始化了两次。

改进2

动态原型模式,保证原型初始化的唯一性

function Box1(name,age){ //不共享的使用构造函数
this.name=name;
	this.age=age;
	this.family=['爸爸','妈妈','哥哥'];
//条件判断原型是否已经被初始化
if(typeof this.run!='function'){
	Box.prototype. run=function(){ //原型方法
return this.name+this.age+this.family;
	}
	}
};

var box1=new Box1('Lee',100);
alert(box1.run());
var box2=new Box1('Jack',200);
alert(box2.run()); 

3.总结

从编织知识网出发,原型模式类似于设计模式中的继承。原型对象相当于父类,特定类型的实例对象相当于子类,原型里面的方法和属性可以被这些特定类型的实例对象共享,而这些实例对象又可以在私有的作用域内个性化操作即重写从原型共享得到的方法或属性,但是这些修改不会影响原型对象(引用类型属性除外)。

时间: 2024-10-17 15:45:12

浅析JavaScript原型的相关文章

浅析JavaScript闭包

闭包和原型是javascript语言的两大特点,上篇博文<浅析JavaScript原型>中已经总结了原型 ,今天就总结一下闭包的相关知识. 前言 在开始闭包之前,需要先介绍一下匿名函数和JavaScript垃圾回收机制这两个概念. 匿名函数 匿名函数,很容易理解,就是没有名字的函数. //普通函数 function box(){ return 'This's just a test'; } //匿名函数的架构思想,但是这样写会报错 function (){ return 'This's jus

浅析JS原型对象&amp;实例对象&amp;构造函数(转)

浅析原型对象,实例对象,构造函数的关系 原文地址:JS面向对象-原型对象,实例对象,构造函数的关系(http://blog.csdn.net/u014205965/article/details/45798861) 因为最根上的object拥有一个prototype属性,而js中所有的对象又都继承自object,所以js中所有的对象都拥有一个prototype属性,而在js中函数也是对象,所以js中每个函数也都有一个prototype属性. 例如:function Person(){...} 和

javascript原型Prototype

在javaScript创建对象一文中提到过:用构造函数创建对象存在一个问题即同一构造函数的不同实例的相同方法是不一样的,所以我们用原型把构造函数中公共的属性和方法提取出来进行封装,达到让所有实例共享的目的. 接下来进一步介绍javaScript原型. 一.javaScript原型机制 1.函数与原型的关系 js中创建一个函数,就会自动创建一个prototype属性,这个属性指向函数的原型对象,并且原型对象会自动获得一个constructor(构造函数)属性,指向该函数. 举例:以前面的原型模式创

javascript原型,组合,动态原型,稳妥构造函数式

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getS

JavaScript之基础-16 JavaScript 原型与继承

一.JavaScript 原型 原型的概念 - 在JavaScript中,函数本身也是一个包含了方法和属性的对象 - 每个函数中都有一个prototype属性,该属性引用的就是原型对象 - 原型对象是保存共享属性值和共享方法的对象 为对象扩展属性 - 扩展单个对象的成员 - 扩展共享的属性值 - 内存图描述 删除属性 - 可以使用delete关键字删除对象的属性 自由属性与原型属性 - 自有属性:通过对象的引用添加的属性;其它对象可能无此属性;即使有,也是彼此独立的属性 emp1.job = '

理解JavaScript原型

Javascript原型总会给人产生一些困惑,无论是经验丰富的专家,还是作者自己也时常表现出对这个概念某些有限的理解,我认为这样的困惑在我们一开始接触原型时就已经产生了,它们常常和new.constructor相关,特别是函数(function)的原型(prototype)属性(property).事实上,原型是一种非常简单的概念.为了更好的理解它,我们应该首先记住这个原则,那就是忘记我们已经学到的关于构造原型(construtor prototypes)的认识. 什么是原型? 原型是一个对象,

深入理解JavaScript原型链

前言 最近碰到一个题,大家可以试下. Object.prototype.a = function() { console.log("aaa "+this.name); }; Function.prototype.b = function() { console.log("bbb "+this.name); }; function Person(name) { this.name = name; } var person = new Person("Chin

javascript原型

在javaScript创建对象一文中提到过:用构造函数创建对象存在一个问题即同一构造函数的不同实例的相同方法是不一样的,所以我们用原型把构造函数中公共的属性和方法提取出来进行封装,达到让所有实例共享的目的. 接下来进一步介绍javaScript原型. 一.javaScript原型机制 1.函数与原型的关系 js中创建一个函数,就会自动创建一个prototype属性,这个属性指向函数的原型对象,并且原型对象会自动获得一个constructor(构造函数)属性,指向该函数. 举例:以前面的原型模式创

深入理解javascript原型和闭包(15)——闭包

http://www.cnblogs.com/wangfupeng1988/p/3994065.html 深入理解javascript原型和闭包(15)——闭包