Javascript,原型和继承

时间:2014-02-01 17:01:14

标签: javascript

我有这段代码:

var Parent = function(){};
var Child = function(){};

function inherit(C, P){
    C.prototype = new P();//received a pointer to Parent
    C.prototype.test = function(){};
}

inherit(Child, Parent);
console.log(new Parent);//Object {}
console.log(new Child);//Object {test=function()}

现在我有一个问题,如果C.prototype在我的继承函数中收到了一个指向Parent的指针,为什么我的“console.log(new Parent)”没有显示如下:“Object {test = function() “to Parent和”Object {}“to Child?

3 个答案:

答案 0 :(得分:3)

取出要简化的功能;

var Parent = function(){};
var Child = function(){};

Child.prototype = new Parent();//"received a pointer to Parent"
Child.prototype.test = function(){};

console.log(new Parent);//Object {}
console.log(new Child);//Object {test=function()}

Child.prototype现在是对Parent实例的引用,为了说明,您所做的也可以写成:

var Parent = function(){};
var Child = function(){};

var instance = new Parent();
instance.test = function(){};
Child.prototype = instance;

console.log(new Parent);//Object {}
console.log(new Child);//Object {test=function()}

在实例上放置属性不会影响Parent原型,这就是控制台日志未在Parent原型上显示测试函数的原因。这与做(几乎相同)相同:

var instance = {
    test: function(){}
};
instance.prototype = Parent;

答案 1 :(得分:1)

new P(),在ram中创建一个新空间并存储一个P实例。
不要忘记你改变C.(new P).test,而不是C.P.test,这是有区别的。 new PP有不同的指针,与new P new P相同。检查OOP中的new关键字如Java,然后将其清除。

答案 2 :(得分:0)

为了更好地理解这一点,你必须知道改变对象和重新分配对象之间的区别。

a=22;//assigns value to a
a.something=22;//mutates it
a.push(22);//if a is an array then push will mutate it

正如我在评论中的link中所解释的那样:你不能通过实例重新分配原型成员(Child.prototype是Parent的实例),但你可以改变它们(I建议阅读链接发布)。以下是一些示例代码:

var Test = function(){};
Test.prototype.something={a:1};
Test.prototype.somethingElse={a:2};
var t = new Test();
//mutating someting in t will change 
//  Test.prototype.someting
t.something.a=3;
//re assigning somethingElse will not
// change Test.prototype.somethingElse
// instead it will create a member called
// somethingElse on t 
t.somethingElse=3;
var anotherT =  new Test();
console.log(anotherT.something);//{a=3}
console.log(anotherT.somethingElse);//{a=2}
console.log(t.somethingElse);//3
console.log(t.hasOwnProperty("somethingElse"));//true
//next is false because anotherT.sometingElse comes
// from the prototype chain and not directly from antohrT
console.log(anotherT.hasOwnProperty("somethingElse"));//false

将变量传递给函数时,其工作方式相同:

var assignVal=function(obj){
  obj=22;
};
var mutateVal=function(obj){
  obj.mutated=22;
};

var o = {msg:"Hello World"};
assignVal(o);
console.log(o);//{msg="Hello world"}
mutateVal(o);
console.log(o);//{msg="Hello world",mutated=22}