Pab*_*dez 16 javascript inheritance prototype prototypal-inheritance
我在js做了一些继承,以便更好地理解它,我发现了让我困惑的东西.
我知道当你用new关键字调用'constructor function'时,你得到一个新对象,引用该函数的原型.
我也知道,为了进行原型继承,你必须用你想成为'超类'的对象的实例替换构造函数的原型.
所以我做了这个愚蠢的例子来尝试这些概念:
function Animal(){}
function Dog(){}
Animal.prototype.run = function(){alert("running...")};
Dog.prototype = new Animal();
Dog.prototype.bark = function(){alert("arf!")};
var fido = new Dog();
fido.bark() //ok
fido.run() //ok
console.log(Dog.prototype) // its an 'Object'
console.log(fido.prototype) // UNDEFINED
console.log(fido.constructor.prototype == Dog.prototype) //this is true
function KillerDog(){};
KillerDog.prototype.deathBite = function(){alert("AAARFFF! *bite*")}
fido.prototype = new KillerDog();
console.log(fido.prototype) // no longer UNDEFINED
fido.deathBite(); // but this doesn't work!
Run Code Online (Sandbox Code Playgroud)
(这是在Firebug的控制台中完成的)
1)为什么如果所有新对象都包含对creator函数原型的引用,fido.prototype是未定义的?
2)继承链[obj] - > [constructor] - > [prototype]而不是[obj] - > [prototype]?
3)我们的对象(fido)的"原型"属性是否曾被检查过?如果是这样的话......为什么'deathBite'未定义(在最后一部分)?
Ant*_*nes 12
1)为什么如果所有新对象都包含对creator函数原型的引用,fido.prototype是未定义的?
所有新对象都会在构造时对其构造函数中存在的原型进行引用.但是,用于存储此引用的属性名称prototype
与构造函数本身不同.一些Javascript实现允许通过某些属性名称访问这个"隐藏"属性,就像__proto__
其他属性名称一样(例如微软).
2)继承链[obj] - > [constructor] - > [prototype]而不是[obj] - > [prototype]?
不.看看这个: -
function Base() {}
Base.prototype.doThis = function() { alert("First"); }
function Base2() {}
Base2.prototype.doThis = function() { alert("Second"); }
function Derived() {}
Derived.prototype = new Base()
var x = new Derived()
Derived.prototype = new Base2()
x.doThis();
Run Code Online (Sandbox Code Playgroud)
这警告"第一"不是第二.如果继承链通过构造函数进行,我们将看到"Second".构造对象时,函数prototype属性中保存的当前引用将转移到其原型的对象隐藏引用.
3)我们的对象(fido)的"原型"属性是否曾被检查过?如果是这样的话......为什么'deathBite'未定义(在最后一部分)?
分配给一个对象(函数除外)一个被调用的属性prototype
没有特殊含义,如前所述,一个对象不通过这样的属性名维护对其原型的引用.
一旦对象的原型被实例化,就无法更改它new
.
在上面的例子中,行如
fido.prototype = new KillerDog();
Run Code Online (Sandbox Code Playgroud)
只需创建一个prototype
在对象上命名的新属性fido
,并将该属性设置为一个新KillerDog
对象.它没有什么不同
fido.foo = new KillerDog();
Run Code Online (Sandbox Code Playgroud)
你的代码就是......
// Doesn't work because objects can't be changed via their constructors
fido.deathBite();
// Does work, because objects can be changed dynamically,
// and Javascript won't complain when you use prototype
//as an object attribute name
fido.prototype.deathBite();
Run Code Online (Sandbox Code Playgroud)
特殊prototype
行为仅适用于javascript中的构造函数,其中构造函数是function
将被调用的new
.