function Father(){
console.log('father');
}
function Sub(){
console.log('sub');
}
Sub.prototype = Object.create(Father.prototype);
Sub.prototype.constructor = Sub; //为什么实现继承必须要有这句?没有这句会产生什么后果?
我知道最简单的后果就是Sub.prototype.constructor === Father(){...},然而知道这个貌似也没什么用。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
你认为
Sub.prototype === Father(){...},是不对的,关于JavaScript的面向对象,具体来说是原型这种设计,有几个点需要注意。先说结论:那一句只是为了指明constructor,如果你不用constructor的话,这确实没什么用。
不过你说的
是不对的。
你可以亲自试验一下
题主需要重点了解一下Object.create方法,以及JavaScript的原型链。
特别是区分对象的原型以及构造函数的prototype属性。
另外建议题主把《JavaScript高级程序设计》的第六章再仔细读一读, 尤其注意分析其中的配图。
下面详细说一说:
JavaScript中对象的构建方式
使用字面量构建的对象其原型是Object.prototype,使用Object.create(proto[, propObj])所构建的对象的原型是你所提供的proto,而是用构造函数创建的对象其原型即为构造函数的prototype属性指向的对象。下面提供几段代码以供实验:
我看你在另一个答案下的评论提到了
__proto__是非标准实现,确实是这样的,但是这是目前各个浏览器都采用了的方案,Node.js内部也是使用这种实现的。而且__proto__确实是窥探对象原型(标准中指定的[[Prototype]])的一种方式。这说明Object.create(proto[, propObj])为新对象添加了propObj中指定的属性,还指定了proto为其原型。
这说明在使用new创建对象时,新对象作为this传入构造函数中,并且新对象的
__proto__属性(标准中的[[Prototype]]内部属性)被置为Fruit.prototype,也就是构造函数的prototype属性。这里需要注意区别构造函数的prototype属性,以及构造函数本身作为一种对象(函数也是一种对象)它自己的原型[[Prototype]]。构造函数的prototype属性就是为了指定新对象的原型而存在的,而与函数本身没有太大关系。函数本身的[[Prototype]]可以通过
Fruit.__proto__这种形式窥探到,它实际上是Function.prototype。JavaScript中instanceof的工作方式
instanceof运算符(obj instanceof Constructor)会以obj为参数调用Constructor的[[HasInstance]]内部方法,这个方法的操作就是循着左侧操作符的原型链检查是否有与Constructor.prototype相同的原型,如果有就返回true,否则返回false。
例如:
JavaScript的原型继承
JavaScript的继承采用了原型链这种方式,但又加入了模仿Java、C++中“类”这种概念的成分,因此出现了一些比较令人纠结的概念。
在1.中提到了要区别构造函数的prototype属性以及函数的原型[[Prototype]]、对象的原型这些概念,一旦理清这几个概念,JavaScript的原型继承也就非常清楚了。
把上面的实验操作一遍, 仔细分析结果, 应该就可以理清JavaScript的原型链与构造函数, 构造函数的prototype之间的关系了。
请参考这篇 :http://m.blog.csdn.net/blog/adwu73/7224356
////
标准里面prototype只有一个属性就是constructor,你这里没有写Object.create()的实现,但是从函数名猜下来Sub.prototype = Object.create(Father.prototype);你这句是在把函数的prototype属性的prototype对象替换成Father,也就是要继承的那个,可是问题随之而来了,你替换了之后,prototype的constructor也是一并被换了,而constructor是指向自身的,Sub的prototype的constructor指向sub自己,Father的也指向自己,也就是没有下面那句的话,Sub的constructor是指向了Father,这样你用new之后,完蛋了,类的实例们突然发现,不知道(爸爸)类去哪了,prototype里放了要继承的Father的属性和方法,可是constructor也指向了要继承的Father,原来的Sub没他什么事情了。注意只有Function有prototype,而new之后的实例是没有prototype,它只有一个东西指向类的prototype。总之就是,类中只有一个属性prototype,prototype属性有一个prototype对象,我们继承就是通过在prototype中放要继承的Father的属性和方法来实现继承的。但是即便我们什么东西也没有放,prototype中也有一个constructor属性,此属性指向自身。我们替换prototype不能把constructor也换掉。如果你还不是很清楚,我会晚些时候写一些例子。
//