javascript 里子类型的构造函数的实例为什么不能向父类型的构造函数实例传递参数?

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.ob = job;
}

function Man(name,age,job,mustache){
    this.mustache = mustache;
    Man.prototype = new Person(name,age,job);
}

var m = new Man('Anthony',27,'PE');
m.name;//undefined

这里的m.name 是undefined 的,但是可以确定的是在构造函数体内是可以访问构造函数本身的原型的,如下:

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.ob = job;
    if(typeof this.sayName != 'undefined'){
        Person.prototype.sayName = function(){
           alert(this.name)
        }
    }
}

var p = new Person('anthony',29,'PE');
p.sayName();//anthony
阅读 4.5k
6 个回答

这道题有点‘君生我未生,我生君已老’的意思吧。
你大可以在后面再生成一个Man的实例,查看它的name属性

function Man(name,age,job,mustache){
    // 当执行 m = new Man(); 的时候,`this.__proto__ = Man.prototype`
    // 是在这里执行的,所以下面改变Man.prototype并没有什么效果。
    this.mustache = mustache;
    Man.prototype = new Person(name,age,job);
}
var m = new Man('anthony1',29,'PE');
m.name; // "undefined"
var b=new Man()
b.name//27

在生成m实例的时候,Man.prototype还不是一个Man的实例。其后再生成一个Man实例时,Man.prototype已经变成你前面设置的样子。

读取一个对象(obj)的属性(property)时候,其实解释器查找的是
obj.property obj.__proto__.property...找到的第一个。
而:

function Man(name,age,job,mustache){
    // 当执行 new Man(); 的时候,`this.__proto__ = Man.prototype`
    this.mustache = mustache;
    // 这句发生在原型链发生之后,所以不行
    Man.prototype = new Person(name,age,job);
}

这样写是不行的。但是可以这样:

function Man(name,age,job,mustache){
  // 不太建议新手研究这段代码。
    var fn(){};
    fn.prototype = new Person(name,age,job);
    var that = new fn();
    that.mustache = mustache;
    return that;
}

这样,m = new Man();那么m.name就是你想要的值了,其实他是 m.__proto__.name;但是它是只读的,所以 m.name = "newName" 其实只是重新给m创建了一个熟悉name,原来的m.__proto__.name还是存在的(但是保存它没有什么意义).
而且,m instanceof man 也也是不工作的。总上,这样做一点儿好处也没有反而有很多的坏处,所以还是正统的写法比较好。

第二段代码工作的原因是,Person.prototype.sayName=... 并没有改变Person.prototype只是给他添加了新的属性。如果继承如同这段代码一样:

function Man(name,age,job,mustache){
    this.mustache = mustache;
    Person.call(Man.prototype,name,age,job);
}

这样,程序里只存在一个Man.prototype,而要创建多个Man类型的对象,怎么保存多个名字?????!

关于原型链参考:http://zonxin.github.io/post/...

new操作符在为新对象设置原型继承 (将新对象的__proto__设为构造函数的prototype) 之后 才会调用构造函数。所以

function Man(name,age,job,mustache){
    this.mustache = mustache;
    Man.prototype = new Person(name,age,job);
    // 这个地方把Man.prototype换成一个新的对象,不会影响 *这一个* new Man()得到的对象的原型(会影响下一个
}
function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
}

function Man(name,age,job,mustache){
    this.mustache = mustache;
    // 改成这句话
    Person.call(this, name,age,job)
    Man.prototype = new Person();
}

var m = new Man('Anthony',27,'PE');
m.name;// Anthony

关于委托或者继承,可以用

Man.prototype = Object.create(Person.prototype);

既然是继承,子类向父类传递参数是什么鬼?

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.ob = job;
}

function Man(name,age,job,mustache){
    this.mustache = mustache;
    Man.prototype = new Person(name,age,job);
}

var m = new Man('Anthony',27,'PE');
m.name;//undefined

当通过new操作符创建一个Man对象实例m时,JS引擎会首先创见一个对象,this关键字指向这个对象,并且其原型对象为函数的默认原型对象A;
在函数Man的执行过程中其原型对象发生变化,指向了Person的实例对象B,但是这个并不能改变当前this关键字指向的对象及其原型对象A
当Man函数执行结束后,this关键字指向的对象赋值给m,那么m的__proto__指向的原型对象为Man的默认原型对象A
而Man函数的原型对象变更为B

导致的结果为
第1次执行new Man后,Man的prototype被改变为B,但是创建的实例的指向的原型对象A并不发生变化,也就是实例的__proto__执行不发生变化。
第2次执行new Man后,Man的prototype被改变为C,创建的实例的指向的原型对象B并不发生变化,也就是实例的__proto__执行B。
第2次执行new Man后,Man的prototype被改变为D,创建的实例的指向的原型对象C并不发生变化,也就是实例的__proto__执行C。

其根本还是变量赋值的问题,如下

var obj1={
    name:"XXXX"
};
var testObject={};

testObject.obj1=obj1;

//obj1重新赋值,但并不影响testObject.obj1执行的对象,虽然一开始的时候2者时相同的
obj1={
    name:"YYYY"
};

console.log(testObject.obj1.name);//XXXX
console.log(obj1.name);//YYYY
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题