面向对象中的原型和原型链

今天我们要说的是面向对象中的原型链,在说原型链之前,我们先一步一步来了解一下面向对象中的一些基本概念。

一.类

类是指具有相同特征(属性)和行为(方法)的事物的集合。

二.对象

对象的目的实际上是将具有相同属性和行为的代码整合在一起,方便我们的管理。

起初,我们是这样来创建一个对象的,

js代码:

var person1 = {
    name:"张三",
    age:18,
    height:165,
    walk:function(){
        console.log("i can walk!");
    }
}

但是这样的话,会有一个问题,我们每调用一个对象都要重复上面的代码,就比如,我们再定义一个person2我们就需要再重复上面的代码,name,age。。。那么怎么来解决这个问题呢?

三.构造函数

为了解决上面的问题,我们就可以想,我们能不能定义一个函数来解决这个问题呢?因为作为“人”这个类,它们都具有上面的属性(name,age,height)和方法(walk),OK,我们来看一下下面这段代码

js代码:

 var person = function(_name,_age,_height){
        var obj = new Object();
        obj.name = _name;
        obj.age = _age;
        obj.height = _height;
        obj.walk = function(){
            console.log("i can walk!");
        }
        return obj;
 }
 var person2= new person("小花",8,140);  //创建新对象

这个是我们所立刻就能想到的一般的创建函数的方法,它确实比我们第一种创建对象的方法简单得多,但是。。。这还不够简单,下面我们就来引进“构造函数”这个概念,因为它比上面那种我们一般创建函数的方法更简单,我们来看一下

function Person(_name,_age,_height){
    this.name = _name,
    this.age = _age,
    this.height=_height,
    this.walk = function(){
        console.log("i can walk!");
    }
}
var person2 = new Person("阳阳",18,160);

没错,上面这段代码中的函数就是我们创建的构造函数,它的机制在于,会自动创建一个空对象,然后与this相关联,并作为默认返回值返回,通过构造函数我们就不用反复定义属性和方法,是不是比上面简单了一点。需要注意的是,我们在创建构造函数的时候,构造函数的首字母一定要大写。

四.原型

在上面的构造函数中,每个对象的属性(name,age,height)都是不一样的,我们每创建一个对象都要去调用构造函数去分配一定的内存空间进行存储,这个可以理解,但是,对于walk方法,它是每个对象都共有的方法,我们还要每创建一个对象都要去调用构造函数去分配一定的内存空间去存储它,好像是有点浪费资源对不对,没关系,我们接下来就引入另一个概念--原型。

我们先来说一下原型究竟是个什么意思?我们刚说过,对于一些共有方法,我们每次创建对象都要重复的去为它们分配空间,很占用空间。而原型就是为了解决空间被过多占用的问题,每一个函数在创建的时候都会默认的分配一个prototype属性,构造函数也不例外。prototype是一个指针,它指向一个对象,它的特点就是在内存中只有一份。总结起来就是:

将方法定义到函数的prototype上,这样的好处是,通过该构造函数生成的实例所拥有的方法都是指向一个函数的索引,这样可以节省内存。看下代码

function Person(_name,_age,_sex){
    this.name = _name;
    this.age = _age;
    this.sex = _sex;
}
Person.prototype = {
    walk:function(){
        console.log("i can walk!");
    }
}
var person3 = new Person("盈盈",20,160);
var preson4 = new Person(“笑笑”,22,167);
       

在上面的代码中,我们虽然也是定义了两个对象,但是我们在调用方法的时候,他们都是去prototype中调用的这个函数,而这个方法在内存中只有一份,就是通过这种方法我们节省了内存。

五,面向对象中的继承

在说原型链之前,我们还要提的就是面向对象中的继承问题,是不是心很累,但是这个对下面我们理解原型链是非常重要的。面向对象有三大特征,封装,多态,还有就是继承,这里,我们只看继承,我们先来看一下,面向对象中的继承机制是怎样的。这里的继承包括构造函数的继承,和原型的继承。

首先,我们来看一下,构造函数的继承,

function Student(_name,_age,_sex,_grade){
    this.name = _name;
    this.age = _age;
    this.sex = _sex;
    this.grade = _grade;
}
var stu1 = new Student("盈盈",22,"女",100);//创建第一个对象
console.log(stu1.name);  //盈盈

上面是我们新定义的一个构造函数。它跟上面我们定义的Person有一些共同的属性name,age,height,下面我们就通过构造函数的继承方式创建构造函数Student

function Student(_name,_age,_sex,_grade){
    //Person.call(this,_name,_age,_sex); //方法一
    Person.apply(this,[_name,_age,_sex]);//方法二
    this.grade = _grade;
}
var stu1 = new Student("盈盈",22,"女",100);
console.log(stu1.name);//盈盈

下面我们再来看一下原型的继承

原型的继承是通过将

原型的继承是通过将要创建的原型作为已创建原型的一个实例化对象,这样他就可以继承已创建构造函数的方法,并且还可以在此基础上去扩展自己的方法

下面我们通过具体的完整代码来看一下

function Person(_name,_age,_height){
    this.name = _name,
    this.age = _age,
    this.height=_height
}
Person.prototype = {
    walk:function(){
        console.log("i can walk!");
    }
}
var person1 = new Person("阳阳",18,165);
function Student(_name,_age,_sex,_grade){
       this.name = _name;
    this.age = _age;
    this.sex = _sex;
    this.grade = _grade;
}
Student.prototype  = new Person("姣姣",18,"女");
var stu1 = new Student("盈盈",22,"女",100);
stu1.walk();   //i can walk!

在上面这个代码中,stu1就继承了Person的walk方法。

除了可以继承它还可以扩展自己的方法

Student.prototype  = new Person("姣姣",18,"女");
Student.prototype.info = function(){
    console.log("i can dance!");
}
var stu1 = new Student("盈盈",22,"女",100);
stu1.walk();  //i can walk!
stu1.info(); //i can dance!

需要注意的是,上面扩展Student原型中的方法只能通过Student.prototype.info=function(){}不能通过Student.prototype = function(){}因为后者会产生覆盖!

六.原型链

真是千呼万唤始出来啊,终于到我们的原型链了,通过上面的介绍原型链的理解对我们来说就不难了。

当对象尝试获取某个属性或者方法时,若该对象的构造函数没有会到该构造函数的原型中去找,若原型也没有,会去原型对象的原型去找,最终到达Object.prototype.

通过上面所讲解的面向对象中的继承,我们应该很容易就理解这句话了吧。

时间: 2024-11-03 20:45:59

面向对象中的原型和原型链的相关文章

JS中面向对象的,对象理解、构造函数、原型、原型链

6.1 理解对象 6.1.1 对象属性类型 ECMS属性有两种类型:数据属性和访问器属性 1 数据属性 [[configurable]] 表示能否通过Delete 删除属性从而从新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性.对象上定义的属性默认值为true [[enumerable]] 表示能否通过for-in循环返回属性.直接在对象上定义的属性,它们的这个特性默认值为true [[writable]] 表示能否修改属性值.像前面例子中那样直接在对象上定义的属性,它们默认值为t

javascript面向对象系列5——知识点(原型和原型链)

基本概念 [原型链]每个构造函数都有一个对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针.那么,如果原型对象等于另一个原型的实例,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针.如果另一个原型又是另一个原型的实例,那么上述关系依然成立.如此层层递进,就构成了实例与原型的链条. [原型对象]这个对象包含可以由特定类型的所有实例共享的属性和方法.所有引用类型默认都继承了Object,而这个继承也是通过原型链实现

原型和原型链 —javascript面向对象高级

原型 1.原型有什么用:js是用原型来实现继承 2.原型是:每一个对象都有其原型对象__proto__,这个原型对象指向构造它的构造函数的原型属性prototype. ## 一.函数和对象的关系 ## 1.函数是对象的一种,instanceof 可以判断 2.对象是函数创建的 ## 二.prototype 与 __proto__ ## 1.prototype是函数的一个属性,每一个函数都有protptype属性,这个值是一个对象,里面有一个constructor属性,指向它自己. 2.__pro

javascript中的原型与原型链

javascript是一门面向对象的语言,但它却没有像其他面向对象的语言(如java,C++)有类的概念,也没有基于类的继承体系.但是它有自己独特的继承方式,那就是基于原型和原型链的继承. 当我们创建一个对象时,每个对象在生成之后都有一个隐式的属性__proto__(非规范,暂且这么叫吧),该属性指向该实例的原型对象,并共享其原型对象上的属性和方法. 下面分析下不同创建对象的方式所对应的__proto__属性指向的不同. 1.用对象字面量创建对象. var a={x:1}; console.lo

快速理解JS中的继承与原型链

语言是用来表达的工具.当我们需要代指某个东西的时候,通常称其为一个对象.在编程语言中,对象并不像真实世界中那样随处可见,随口可以指代.通常我们只有少数的原生对象,剩下的,需要我们自己去创建.在Java语言中,创建一只会“咯咯咯”叫的鸡时,我们是这么做的: public class Chicken{ public void makeSound(){ System.out.println("咯咯咯"); } } Chicken littleChicken = new Chicken();

JavaScript中的继承(原型链)

一.原型链 ECMAScript中将原型链作为实现继承的主要方法,基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法. 实例1: function SupType() { this.property = true; } SupType.prototype.getSupvalue = function() { return this.property; }; function SubType() { this.subproperty = false; } //原型对象等于一个类型的实例

JS中原型与原型链

一. 普通对象与函数对象 JavaScript 中,万物皆对象!但对象也是有区别的.分为普通对象和函数对象,Object .Function等 是 JS 自带的函数对象.下面举例说明. var o1 = {}; var o2 =new Object(); var o3 = new f1(); function f1(){}; var f2 = function(){}; var f3 = new Function('str','console.log(str)'); console.log(ty

javascript中的原型和原型链(二)

原型(prototype) 函数的 prototype 属性(图) 每个函数都有一个prototype属性,它默认指向一个Object空对象(即称为:原型对象) 原型对象中有一个属性constructor,它指向函数对象 给原型对象添加属性(一般都是添加方法) 作用:函数的所有实例对象自动拥有原型中的属性(方法) 显式原型与隐式原型 每个函数 function 都有一个prototype属性,即 显式原型 每个实例对象都有一个__proto__,可称为隐式原型 实例对象的隐式原型的值 === 其

Js中的对象、构造函数、原型、原型链及继承

1.对象 在传统的面向过程的程序设计中,会造成函数或变量的冗余.而JS中对象的目的是将所有的具有相同属性或行为的代码整合到一起,形成一个集合,这样就会方便我们管理,例如: var person1={    name:"tan",    age:26,    showMessage:function(){        alert("name:"+this.name);    }};person.showMessage();//输出name:tan 以上的例子将nam