昨晚再看类继承的方法,碰到一些疑问,请大家帮我解答一下!不求灵光一闪一下就学会了类继承,只求慢慢积累,终会达到自己的想要的!
发布于 1 年前 作者 yss1993 1041 次浏览 来自 问答

问题一 代码如下

function Animal () {
this.name = 'animal';
}
Animal.prototype.sayName = function () {
console.log(this.name);
}
var animal = new Animal();
console.log(animal);

我已经给Animal定义了类sayName,为什么我在console.log实例化后的Animal,只出现了this.name = ‘animal’,没有出现我定义的类sayName?

问题二 代码如下

function Animal () {
this.name = 'animal';
}
Animal.prototype.sayName = function () {
console.log(this.name);
}

function Person () {}

Person.prototype = Animal.prototype;
Person.prototype.constructor = 'Person';
var person = new Person();
console.log(person);

Person已经继承了Animal,为什么我console.log person.name的值是undefined,并且console.log person是一个空的对象?Person.prototype.constructor = ‘Person’;这句代码又是做什么用的?constructor是构造函数,在类实例化的时候会自动调用里面的方法,在这里是不是也可以这样理解? , 我对类的相关知识仅仅处于基础阶段,还不能学以致用,总感觉自己走进了一个死胡同,很是苦恼啊。。。

13 回复

第一个是因为,sayName 是 animal 实例原型链上的属性,而不是 animal 实例本身的属性,所以你 console.log(animal) 只输出 { name: 'animal' },你可以用 __proto__ 来访问到 sayName:console.log(animal.__proto__),这样设计的好处就是所有的 Animal 类的实例可以共享原型链上的方法 sayName,而不是给每一个实例本身都设置这个方法,减少了内存消耗

第二个你的继承不完整,你只让 Person 类的原型等于(其实也不是继承,就是原型链指向同一个)了 Animal 类的原型,而少了一句 function Person () {Animal.call(this)} 来绑定实例本身的属性

如果对继承比较疑惑的话,可以直接用 ES6 的 class 和 extends 关键字,这样基本上和其它的 OOP 风格语言差不多的意思

@hyj1991 谢谢您的回复!您的回复讲得非常清楚了!谢谢!

@woyigmwwwhw 这是占位置吗 hhhhhh

@yss1993 差不多 hhhh <br><br>来自<a href=“https://lzxb.github.io/react-cnode/” target="_blank">react-cnode手机版</a>

@hyj1991 我还有一个疑问

function Animal () {
this.name = 'animal';
}
Animal.prototype.sayName = function () {
console.log(this.name);
}

function Person () {}

Person.prototype = Animal.prototype;
Person.prototype.constructor = 'Person';

console.log(Person.prototype.constructor);
console.log(Animal.prototype.constructor);

在这里的结果全部都是Person,按照我的想法是,Person是继承的Animal,改变

Person.prototype.constructor

的结果不会改变

Animal.prototype.constructor

的结果,但实际上却改变了,这个是为什么呢?

@yss1993 你都写了 Person.prototype = Animal.prototype,Person.prototype 和 Animal.prototype 指向了同一个对象,你修改 Person.prototype.constructor 当然会一起改了,就好像

let a = {name: a};
let b = a;
b.name = 'b'
console.log(a)

一个道理

现在都es6了为什么不直接使用class

@hyj1991 好的 就好比是两个变量(我就打个比方)指向了同一个内存,其中一个变量的值改变,另外一个变量的值也一定会改变一样。再次万分谢谢~

@glj1102 多谢回复!我用node虽然快一年了 但是一直没有使用过es6,就好比是不知道有一个宝藏的存在一样 /大哭

只接使用class吧,使用extends继承就行。建议lz熟悉下原型链

你应该了解 new 到底做了什么

new Animal('cat') = {
    var obj = {};
    obj.__proto__ = Animal.prototype;
    var result = Animal.call(obj,"cat");
    return typeof result === 'object'? result : obj;
}

类就是代码的封装,方便重复利用,你强行记一下a类的实例用b类的方法该怎么做,a类的实例用b类属性又改怎么做。如果是java语言一个关键字就可以搞定了。

回到顶部