原型、实例化、原型链

在使用面对对象编程时,对象间的继承关系自然少不了!而原型正是实现javascript继承的很重要的一种方法!JS的原型链只针对 对象,仅对象才具有的!!!

function person(name, age) {
  this.name = name;
  this.age = age;
}
person.prototype.getInfo = function() {
  alert("My name is "+this.name+", and I have "+this.age+" years old");
}
var zhangchen = new person("zhangchen", 23);
zhangchen.getInfo(); //output My name is zhangchen, and I have 23 years old; 

  从运行的结果我们可以看出,通过关键字new创建的zhangchen这个对象继承了person中通过原型定义的getInfo()方法.

下面我们具体来看新建的zhangchen这个对象是如何继承person对象的属性和方法的。

  原型:在使用javascript的面对对象编程中,原型对象是个核心概念。在javascript中对象是作为现有实例(即原型)对象的副本而创建的,该名称就来自于这一概念。此原型对象的任何属性和方法都将显示为 从原型的构造函数创建的 对象的 属性和方法。当创建zhangchen对象时:

var zhangchen = new company("zhangchen", 23); 

可以说,这些对象从其原型继承了属性和方法。

  zhangchen所引用的对象将从它的原型继承属性和方法,对象zhangchen是由new方法  通过 company("zhangchen",23)函数构建得来的

在javascript中,每个函数都有名为prototype的属性,用于引用该函数的原型对象。该函数对应的原型对象又有名为constructor的属性,它反过来引用函数本身。

这是一种循环引用,如下图

  现在,通过new运算符将函数(person)构建成对象时,所获得的对象将继承person.protype的属性。在上图,可以看到person.prototype对象有一个回指person函数的构造函数属性。这样,每个person对象(从person.prototype继承而来)都有一个回指person函数的构造函数属性。

person.prototype 和 person实例中还可以调用其他方法,比如toString、toLocaleString和valueOf,但它们都不来自person.prototype。而是来自于javascript中的Object.prototype,它是所有原型的最终基础原型。( Object.prototype 的原型是 null )

原型链:每个JavaScript对象都继承一个原型链,而所有原型链都终止于Object.prototype。注意,这种继承是活动对象之间的继承。它不同于继承的常见概念,后者是指在声明类时类之间的发生的继承。因此javaScript继承动态性更强。它使用简单算法实现这一点,如下所示:当你尝试访问对象的属性、方法时,javaScript将检查该属性、方法是否是在该对象中定义的。如果不是,这检查对象的原型。如果还不是,则检查对象的原型的原型,如此直到Object.prototype。

以上看的不是很明白 讲的这个对象那个对象傻傻分不清 没关系 看看下面这篇:

一、初始原型

  在javaScript中,原型也是一个对象,通过原型可以实现对象属性继承(上一层的属性,下一层属性可以调用),javaScript的对象都包含了一个“[[Prototype]]”作为对象的内部属性,这个属性对应的就是该对象的原型 “[[Prototype]]"作为对象的内部属性,是不能被直接访问的。所以为了方便查看一个对象的原型,Firefox和Chrome中提供了_proto_这个非标准属性(不是所有浏览器都支持)的访问器(ECMA引入标准对象原型访问器“Object.getPrototype(object)”)。在javaScript的原型对象中,还包含一个“constructor”属性,这个属性对应创建所有指向该原型的实例的构造函数---这句话这麽拗口,那到底是什么意思呢!!?  很简单 constructor属性   原型  能够通过new方法得到该原型的函数  这句话涉及到的三个知识点;就是指 原型 能够通过 constructor属性 得到 所有 能够通过new方法得到该原型的函数③ ,另外补充的一点当函数通过new方法创建原型对象时,如果出错,在“错误的”(不是我们想要的)原型中 constructor属性 会指出错误原因!

var person = function(name,age){
  this.name = name;
  this.age = age;
}
var p1 = new person();  //不会报错 但所有属性都是undefined 缺少参数!
function a(name,age){alert(1);}
a(); //无参数 可以调用 不会报错(函数体内不涉及到参数)
//constructor 当你实例化某个对象时,必须要给出指定的参数 又叫构造方法

  那么有人就有问题了,new方法是什么呢?不急,向下看!

二、规则

在javaScript中,每个函数 都有一个prototype属性,当一个函数被用作构造函数来创建实例时,这个函数的prototype属性值会被作为原型赋值给所有对象实例(也就是设置 实例的‘_proto_’属性),也就是说,所有实例的原型引用的是函数的prototype属性。(‘只有函数对象才会有这个属性!’

 New方法的过程分为三步(new方法又称为实例化)

var p = new Person(‘张三‘,20);

  1. var p={};初始化一个对象p。

   2. p._proto_=Person.prototype;将对象p的_proto_属性设置为Person.prototype

   3. Person.call(p,"张三",20);调用构造函数Person来初始化p。关于call、apply使用

三、初识object

  Object对象本身是一个函数对象。(CODE TEST)既然是Object函数,就肯定会有Prototype属性,所以可以看到"Object.prototype"的值就是"Object{}"这个对象。反过来,当访问"Object.prototype"对象的"constructor"(构造器)这个属性的时候,就得到了Object函数。

  另外,当通过"Object.prototype._proto_"获取Object原型的原型的时候,将会得到"null",也就是说"Object{}"原型对象就是原型链的终点了。这里会有人喜欢出面试题:原型链的根只能为Object!× 还能为null

四、初识Function

对于所有的对象,都有_proto_属性,这个属性对应该对象的原型。

对于函数对象,除了_proto_属性之外,还有Prototype属性,当一个函数被用作构造函数来创建实例时,该函数的prototype属性值将被作为原型赋值给所有对象实例(也就是设置实例的_proto_属性)

原型链

因为每个对象和原型都有原型,对象的原型指向原型对象,而父的原型又指向父的父,这种原型层层连接起来的就构成了原型链。

一、属性查找

  当查找一个对象的属性时,javaScript会向上遍历原型链,直到找到给定名称的属性为止,到查找到达原型链的顶部(也就是Object.prototype),如果仍然没有找到指定的属性,就会返回undefined。

function Person(name, age){
    this.name = name;
    this.age = age;
  }
Person.prototype.MaxNumber = 9999;
Person.__proto__.MinNumber = -9999;
var will = new Person("Will", 28);
console.log(will.MaxNumber); // 9999
console.log(will.MinNumber); // undefined 

  在这个例子中分别给”Person.prototype “和” Person._proto_”这两个原型对象添加了”MaxNumber “和”MinNumber”属性,这里就需要弄清”prototype”和”proto”的区别了:

  "Person.prototype"对应的就是Person构造出来所有实例的原型,也就是说"Person.prototype"属于这些实例化原型链的一部份,所以当这些实例进行属性查找时候,就会引用到"Person.prototype"中的属性。

   对象创建方式影响原型链

var July = {
   name: "张三",
   age: 28,
   getInfo: function(){
     console.log(this.name + " is " + this.age + " years old");
   }
 }
console.log(July.getInfo()); 

  当使用这种方式创建一个对象的时候,原型链就变成下图了,July对象的原型是“Object.prototype”也就是说对象的构建方式会影响原型链的形式

总结:

  1、在javascript中,每一个函数实际上都是一个函数对象

  2、原型链的根原型为Object,即所有原型的最上层原型都为Object

  3、所有的对象都有_proto_属性,该属性对应该对象的原型

  4、所有的函数对象都有prototype属性,该属性的值会被赋值给该函数创建的对象的_proto_属性。

  5、注意:函数对象没有_proto_属性,对象没有prototype属性

  6、所有的原型对象都有constructor属性,该属性对应创建所有指向该原型的实例化的构造函数

  7、函数对象和原型对象通过prototype和constructor属性进行相互关联。

文章来自 “编程的人”,

原文地址:https://www.cnblogs.com/wssjzw/p/8311713.html

时间: 2024-10-11 04:04:00

原型、实例化、原型链的相关文章

JavaScript学习总结(五)原型和原型链详解

转自:http://segmentfault.com/a/1190000000662547 私有变量和函数 在函数内部定义的变量和函数,如果不对外提供接口,外部是无法访问到的,也就是该函数的私有的变量和函数. <script type="text/javascript"> function Box(){ var color = "blue";//私有变量 var fn = function() //私有函数 { } } </script> 这

L--js原型和原型链

私有变量和函数 在函数内部定义的变量和函数如果不对外提供接口,外部是无法访问到的,也就是该函数的私有变量和函数. <script type="text/javascript"> function Box() { var color = "blue"; //私有变量 var fn = function() {}; //私有函数 } var obj = new Box(); alert(obj.color); //undefined alert(obj.fn

总结一下js的原型和原型链

最近学习了js的面向对象编程,原型和原型链这块是个难点,理解的不是很透彻,这里搜集了一些这方面的资料,以备复习所用 一. 原型与构造函数 Js所有的函数都有一个prototype属性,这个属性引用了一个对象,即原型对象,也简称原型.这个函数包括构造函数和普通函数,我们讲的更多是构造函数的原型,但是也不能否定普通函数也有原型.譬如普通函数: function F(){ ; } alert(F.prototype instanceof Object) //true 构造函数,也即构造对象.首先了解下

关于对象、构造函数、原型、原型链、继承

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

你不知道的JavaScript--Item15 prototype原型和原型链详解

用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,可以为其添加函数供实例访问,其它的就不清楚了,最近看了一些 JavaScript高级程序设计,终于揭开了其神秘面纱. 每个函数都有一个prototype属性,这个属性是指向一个对象的引用,这个对象称为原型对象,原型对象包含函数实例共享的方法和属性,也就是说将函数用作构造函数调用(使用new操作符调用)的时候,新创建的对象会从原型对象上继承属性和

原型和原型链详解

许多人对JavaScript的原型及原型链仍感到困惑,网上的文章又大多长篇大论,令读者不明觉厉.我将用最简洁明了的文字介绍JavaScript的原型及原型链. 私有变量和函数 在函数内部定义的变量和函数,如果不对外提供接口,外部是无法访问到的,也就是该函数的私有的变量和函数. 复制代码 代码如下: <script type="text/javascript"> function Test(){ var color = "blue";//私有变量 var

JavaScript学习--Item15 prototype原型和原型链详解

用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,可以为其添加函数供实例访问,其它的就不清楚了,最近看了一些 JavaScript高级程序设计,终于揭开了其神秘面纱. 每个函数都有一个prototype属性,这个属性是指向一个对象的引用,这个对象称为原型对象,原型对象包含函数实例共享的方法和属性,也就是说将函数用作构造函数调用(使用new操作符调用)的时候,新创建的对象会从原型对象上继承属性和

浅谈javascript的原型及原型链

浅谈javascript的原型及原型链 这里,我们列出原型的几个概念,如下: prototype属性 [[prototype]] __proto__ prototype属性 只要创建了一个函数,就会为该函数创建一个prototype属性,指向该函数的原型对象.实例对象是不会拥有该属性的.默认情况下,该原型对象也会获得一个constructor属性,该属性包含一个指针,指向prototype属性所在的函数. Person.prototype.constructor===Person [[proto

js原型和原型链理解 constructor 构造函数

一.对象:普通对象   函数对象 二.构造函数特点:1.需要new实例化,内部使用this对象指向即将要生成的实例对象  2.首字母大写,用于区分普通函数 function Person(name){ this.name=name } var person1=new Person('xiaohong') var person2=new Person('lili') person1.constructor=Person   constructor指向构造函数,Person的内置属性 Person.

图解JavaScript原型和原型链

基础了解 Javascript对象可以分为两类: 普通对象 ,除了函数对象之外的对象都是,包括new函数对象()产生的实例,普通对象没有prototype,也就没有继承和原型链一说. 函数对象 ,包括两种: 由function创造出来的函数: function f1() { } // 匿名函数 var f2 = function() { } var f3 = new Function('x','console.log(x)'); // 以上都是函数对象 系统内置的函数对象: Function,O