JS中的原型与继承

原型:

Js所有的函数都有一个prototype属性,这个属性引用了一个对象,即原型对象,也简称原型。这个函数包括构造函数和普通函数,我们讲的更多是构造函数的原型,但是也不能否定普通函数也有原型。譬如普通函数:

function F(){
  ;
}
alert(F.prototype instanceof Object) //true

构造函数实例化对象的过程。

function A(x){
  this.x=x;
}
var obj=new A(1);

  实例化obj对象有三步:

  • 1. 创建obj对象:var obj=new A(1);
  • 2. 将obj的内部__proto__指向构造他的函数A的prototype.  类的实例对象的constructor属性永远指向"构造函数"的prototype.constructor.  obj是没有prototype属性的,但是有内部的__proto__,通过__proto__来取得原型链上的原型属性和原型方法
  • 3. 将obj作为this去调用构造函数A,从而设置成员(即对象属性和对象方法)并初始化。 (obj作为了this, 故  obj.x = x)

2种方式定义原型方法:

function A(x){
  this.x=x;
    this.say = function(){alert(‘hi‘)}  ;
}

另一种:

A.prototype.say=function(){alert("Hi")};

区别:

前者的话,每一个对象都有关于say方法的一个副本。

后者,这个原型对象的say方法是唯一的副本给大家共享的。(这是通过内部的_proto_链来实现的。)

类继承

简单的继承实现。(js没有类,这里只是指构造函数)

function A(x){
  this.x=x;
}

function B(x2,y){
  this.tmpObj=A;
  this.tmpObj(x2);
  delete this.tmpObj;
  this.y=y;
}

5、6、7行:(临时工角色)

创建临时属性tmpObj引用构造函数A,然后在B内部执行,执行完后删除。

B当然就拥有了x属性:

function A(x){
  this.x=x;
}

function B(x2,y){
  this.x=x2;
  this.y=y;
}

  

当然B的x属性和A的x属性两者是独立,所以并不能算严格的继承。

第5、6、7行有更简单的实现:

A.call(this,x);

  

问题来了

B虽然继承了A构造对象的所有属性方法,但是不能继承A的原型对象的成员。

function A(x){
  this.x=x;
}
A.prototype.a = "a";

function B(x2,y){
  A.call(this, x);
  this.y=y;
}

这样子B里面是没有继承 A.prototype.a = "a"; 属性的!

原型继承

解决上面的问题:

function A(x){
   this.x = x;
 }
 A.prototype.a = "a";
 function B(x2,y){
   this.y = y;
   A.call(this,x2);
 }

B.prototype.b1 = function(){
   alert("b1");
}
B.prototype = new A();  //注意A里面没有带参数!
// B先是被“类继承”一次,又被“原型继承”一次
//故B里面有两个x属性,一个为"a",一个undefined!
//这时,"原型属性x"要让位于"实例对象属性x",还是"a"了。

// 还要注意:此时,B.prototype.constructor就是构造对象A了!
//alert(B.prototype.constructor)出来后就是"function A(x){...}"  下面有解决的

//设置了原型方法b1,但是上面一行,原型指向改变,原来具有b1的原型对象被抛弃,自然又没有b1了

//再来个b2
 B.prototype.b2 = function(){
   alert("b2");
 }
 B.prototype.constructor = B;
// 将B原型的构造器重新指向了B构造函数

// 实例化B一个
 var obj = new B(1,3);

类继承是这行:A.call(this.x);

原型继承是这行:B.prototype = new A();

如果没有

B.prototype.constructor = B;

那是不是obj = new B(1,3)会去调用A构造函数实例化呢?

答案是否定的:

你会发现obj.y=3,所以仍然是调用的B构造函数实例化的。

只是

obj.constructor===A  //true

对于new B()的行为来说,执行了上面所说的通过构造函数创建实例对象的3个步骤:

  • 第一步,创建空对象;
  • 第二步,obj.__proto__ === B.prototype;  (B.prototype是具有x,a,b2成员的。然后obj.constructor指向了B.prototype.constructor,即构造函数A;)
  • 第三步,调用的构造函数B去设置和初始化成员,具有了属性x,y。

原文出处:http://ljchow.cnblogs.com

时间: 2024-09-28 17:36:28

JS中的原型与继承的相关文章

js中的原型、继承的一些想法

最近看到一个别人写的js类库,突然对js中的原型及继承产生了一些想法,之前也看过其中的一些内容,但是总不是很清晰,这几天利用空闲时间,对这块理解了一下,感觉还是有不通之处,思路上没那么条理,仅作为分享, 一.instanceof 在JavaScript有instanceof运算符,是二元运算符,使用方法 instanceA instanceof A,返回值是布尔值(boolean),含义是判断instanceA是否是A的一个实例,其实质是判断A.prototype===instanceA.__p

谈谈JS中的原型

不知道大家对JS中的原型理解的怎么样,我想如果大家对JS中的原型对象以及prototype属性十分熟悉的话对后面原型链以及继承的理解会十分的容易,这里想和大家分享自己对其的理解,请先看下面这段代码O(∩_∩)O~~ 1 function Person(){ 2 } 3 Person.prototype.name = "jingzi"; 4 Person.prototype.age = 20; 5 Person.prototype.sayName = function(){ 6 aler

JS中有关对象的继承以及实例化、浅拷贝深拷贝的奥秘

一.属性的归属问题 JS对象中定义的属性和方法如果不是挂在原型链上的方法和属性(直接通过如类似x的方式进行定义)都只是在该对象上,对原型链上的没有影响.对于所有实例共用的方法可直接定义在原型链上这样实例化的的时候就不用对每个实例定义该属性方法,所有的实例均具有该方的引用见最后的输出. function Myclass(){ this.x=" x in Myclass"; this.get=function(){}//每次实例化对象,每个对象的该方法都是独立的,是不相同的 } Mycla

详解JavaScript中的原型和继承-转自颜海镜大大

本文将会介绍面向对象,继承,原型等相关知识,涉及的知识点如下: 面向对象与继承 CEOC OLOO 臃肿的对象 原型与原型链 修改原型的方式 面向对象与继承 最近学习了下python,还写了篇博文<重拾编程乐趣——我的Python笔记>,加深了我对面向对象的一些理解. 我们会对我们写的程序进行抽象,而不同的语言都提供了不同的抽象工具,比如各种语言里面的数组,集合(键值数组,哈希表,字典等)等提供了对数据的抽象:而VB里面的子程序,类C语言里面的函数,提供了抽象代码段的能力. 有时我们希望将数据

JavaScript中的原型和继承

请在此暂时忘记之前学到的面向对象的一切知识.这里只需要考虑赛车的情况.是的,就是赛车. 最近我正在观看 24 Hours of Le Mans ,这是法国流行的一项赛事.最快的车被称为 Le Mans 原型车.这些车虽然是由"奥迪"或"标致"这些厂商制造的,可它们并不是你在街上或速公路上所见到的那类汽车.它们是专为参加高速耐力赛事而制造出来的. 厂家投入巨额资金,用于研发.设计.制造这些原型车,而工程师们总是努力尝试将这项工程做到极致.他们在合金.生物燃料.制动技术

【转】JavaScript中的原型和继承

请在此暂时忘记之前学到的面向对象的一切知识.这里只需要考虑赛车的情况.是的,就是赛车. 最近我正在观看 24 Hours of Le Mans ,这是法国流行的一项赛事.最快的车被称为 Le Mans 原型车.这些车虽然是由“奥迪”或“标致”这些厂商制造的,可它们并不是你在街上或速公路上所见到的那类汽车.它们是专为参加高速耐力赛事而制造出来的. 厂家投入巨额资金,用于研发.设计.制造这些原型车,而工程师们总是努力尝试将这项工程做到极致.他们在合金.生物燃料.制动技术.轮胎的化合物成分和安全特性上

js中的原型与原型链详解

js中的原型与原型链详解 记住下面三句话就可以理解原型: 所有的函数数据类型都天生自带一个属性Prototype(原型)这个属性的值是一个对象,浏览器会默认给他开辟一个堆内存 在浏览器给prototype开辟的堆内存当中有一个天生自带的属性是constructor,这个属性存储的值是当前函数本身 每一个对象都有一个__proto__的属性,这个属性指向当前实例所属类的prototype(如果不能确定他是谁的实例,都是Object的实例) 原型链:如果引用构造函数的实例想要查找某个属性p的话: 首

JS中的原型继承机制

转载 http://blog.csdn.net/niuyongjie/article/details/4810835 在学习JS的面向对象过程中,一直对constructor与prototype感到很迷惑,看了一些博客与书籍,觉得自己弄明白了,现在记录如下: 我们都知道,在JS中有一个function的东西.一般人们叫它函数.比如下面的代码 js代码: [javascript] view plaincopy function Person(name) { alert(name); } Perso

JS面向对象,原型,继承

ECMAScript有两种开发模式:1.函数式(过程化),2.面向对象(OOP).面向对象的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性和方法的对象.但是,ECMAScript没有类的概念,因此它的对象也与基于类的语言中的对象有所不同.var box = new Object();box.name = 'Lee';box.age = 100;box.run = function(){ return this.name + this.age + '运行中...'; //th