js 关于在子类构造函数中加入call(this)的用意!

先上例子:

function Animal(a,b)
{
	this.a = a;
	this.b = b;

}

function Dog(c)
{
	//Animal.call(this);//注释<1>
}

Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
var dog1 = new Dog('tom');
console.log(dog1);
var animal = new Animal();
console.log(animal);
console.log(dog1 instanceof Animal);

打印结果是:

此时dog1并没有ab属性,只是他的原型对象上有ab属性,然后我们将注释<1>取消,

打印结果是:

这个时候,dog1自己就有了ab属性,这个的意思是重写了父类的构造函数上的this上定义的属性和方法,因为可以这样通俗的理解,加入Animal上定义了this.name = ‘哺乳类’

那么其实如果不重写的话,dog1.name=‘哺乳类‘,这种类名应该是每个类所所独具有的特色,比如这时候dog.name应是=‘狗’,而不是‘哺乳类’,所以重写父类的this定义的东西,达到即继承了父类的名字的属性,又保留自身的空间(这里指的是属性值的自由)。

---------------------------------------------------------------------------------------------------------------------------------

自我拓展一下:

闲着没事,我想是否可以利用dog1将原型对象顶端上的属性改变呢?也就是改变Animal原型对象上的属性,让所有Animal和他的子类实例的某个属性都改变呢,

所以我加了一行代码:Dog.prototype.__proto__.a = ‘d1‘; 这个意思是Dog的原型对象是Animal的一个实例。从实例在去找他的__proto__属性找到了Animal的原型对象。然后

改变他的属性a的值,此时打印console.log(animal.a); animal是Animal的实例。发现打印的是underfine,为什么呢?原型对象上是没有a属性的,a属性原本只是存在于Animal的实例上的,我们加的第一行代码是给Animal的原型对象上加了一个a属性,但是其实Animal在实例化的时候会重写重写this.a = a;因为我们new的时候没有加构造参数,所以打印出undefine,为了验证我的推断,我将Animal的a属性去掉:也就是说Animal现在是这样的:

function Animal(b)
{
	this.b = b;

}

果然,在执行。就打印出了console.log(animal.a); //d1

纯粹是瞎玩,只是思考,子类可以把父类的东东都改变了,这违反了面向对象继承的思想吧,js的灵活度太大,不知道那些框架类的js是如何处理这种情况的,貌似是复制继承的概念!

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-04 01:45:56

js 关于在子类构造函数中加入call(this)的用意!的相关文章

Effective JavaScript Item 38 在子类构造函数中调用父类构造函数

本系列作为Effective JavaScript的读书笔记. 在一个游戏或者图形模拟的应用中,都会有场景(Scene)这一概念.在一个场景中会包含一个对象集合,这些对象被称为角色(Actor).而每个角色根据其类型会有一个图像用来表示,同时场景也需要保存一个底层图形展示对象的引用,被称为上下文(Context): function Scene(context, width, height, images) { this.context = context; this.width = width

JavaSE8基础 子类构造函数中写super语句去显式指定父类的构造函数

os :windows7 x64    jdk:jdk-8u131-windows-x64    ide:Eclipse Oxygen Release (4.7.0)        代码: /* *默认是 子类的构造函数先去调用父类的无参构造函数,但是问题就来,如果父类没有无参构造函数怎么办? *通过super去显式指定父类的构造函数 */ //父类 class Father { //有参构造函数,int public Father(int num) { System.out.println("

关于父类私有属性在子类构造函数中super调用的解释

package test; public class Car { private int carMoney; //汽车租金 private String carName; //汽车名字 private int carNumb; //汽车序列号 private int carryNum; //载货量 private int passengerNum;//载客人数 public Car(int carNumb,String carName,int carMoney,int passengerNum,

C++继承中关于子类构造函数的写法

转载于:http://www.cnblogs.com/kaige/p/cplusplus_virtual_inheritance_derived_class_constructor.html 构造方法用来初始化类的对象,与父类的其它成员不同,它不能被子类继承(子类可以继承父类所有的成员变量和成员方法,但不继承父类的构造方法).因此,在创建子类对象时,为了初始化从父类继承来的数据成员,系统需要调用其父类的构造方法. 如果没有显式的构造函数,编译器会给一个默认的构造函数,并且该默认的构造函数仅仅在没

JS于,子类调用父类的函数

概要 JS虽然没有直接有面向对象的特性,但还是能prototype为了模拟面向对象的特性,如继承和多态.而大多数面向对象的语言(例如C++.Java等一下)相比,JS为了实现面向对象还是有点繁琐,抽象.需要对JS的prototype模式有深刻的理解. 在开发过程中,有时候会遇到这样一个问题:假设在子类中"覆盖"了超类的某个方法,但仍须要在子类方法中调用一次超类方法,这时候应该怎么做?假设是Java,一个简单的superkeyword就可以解决这个问题,但假设是JS呢? 解决这个问题的最

javascript 构造函数中的属性与原型上属性优先级的比较

备注: 下面这个问题是我前天看书上发现的. 按照我以前的理解, a.rename()这个方法传什么值,结果都会弹出 小a,但我看书上的demo 弹出的是大A.... 我的困惑是:  js的构造函数中的属性与方法, 不是比原型对象上的属性与方法优先级要高吗?为什么会弹出的是大A? PS: 小弟很想有人能用通俗易通的语言, 简单的描述下,为什么会弹出的是 A, 而不是小 a.在此谢谢了  function F(name) { this.name = name; } var a = new F("a&

java构造函数是否可继承,以及子类构造函数可否不使用super调用超类构造函数

问题一:java的构造函数能否被继承? 笔者初学java看的一本书说:“java的子类自然的继承其超类的“非private成员”. 通常java的构造函数被设置为public的(若你不写构造函数,java自动添加的无参空构造函数就是public的),因本文中的类都在同一个包中,因此使用无修饰的友好权限说明问题,对于private构造函数的意义,可参见这里. 那么根据该书所述规则,非private的构造函数当然也应该被子类继承. 但实际上,子类不仅无法继承private成员,也无法继承构造函数.

父类与子类 构造函数 变量 加载顺序

http://www.cnblogs.com/mailingfeng/archive/2012/11/23/2784258.html 父的成员变量->构造方法->子的成员变量->子的构造方法注意 如果父亲的构造方法中有被子类覆盖的init方法,当调用init方法的时候由于子的成员变量还未赋值,所以init中使用已经定义的成员变量进行操作是不正确的,把成员 new出来当然没问题啦.使用子的定义的函数当然没关系啦,因为函数是被声明的的. 声明的可以拿来new 赋值,未被初始化的定义不能用的.

js面向对象程序设计之构造函数

再上一篇的开头说了创建对象的两种方式,一种是Object构造函数的方式,一种是对象字面量的方法.但这些方式创建多个对象的时候都会产生大量的重复代码.经过技术的进步也演化出来许多的创建对象的模式.本章会介绍 工厂模式,原型模式,构造函数模式和构造函数与原型模式的混合使用. 1,工厂模式 工厂模式是一个比较广为人知的模式,这种模式将细节抽象出来.代码如下 function createPerson(name,age,job){ var o =new Object(); o.name=name; o.