我不知道JavaScript中有没有继承这个概念。
在Java中继承是指类之间的继承,它的意义在于代码复用和多态,父类A,对应实例对象a,子类B,对应实例对象b,继承指的是类B继承了类A的属性和方法,至于a和b没什么直接关系。
而在JavaScript中好像没有明确的类的概念,它是基于对象的,而这个对象又和Java中的不同,Java中的对象一经实例之后是不能增删属性或方法的,而JavaScript则可以对对象任意修改。Jav中对象是由类实例化得来的,JavaScript中是由函数实例化来的:
var str = new String("实例初始化String");
var obj1 = new Object();
var obj2 = new 自定义函数();
那么我们讨论JavaScript中的继承,是不是就指的是这些函数间的继承呢?
JavaScript中对象的__proto__和继承是不是没有关系呢?
求指点,谢谢每位回复的人!
两种方式:
使用call 改变this
使用 prototype 原型链
es6有标准的class和extend关键字实现继承,其它情况建议使用兼容node的inherits写法。
https://github.com/component/inherits/blob/master/inherits_browser.js
if (typeof Object.create === 'function') {
// implementation from standard node.js 'util' module
module.exports = function inherits(ctor, superCtor) {
ctor.super_ = superCtor
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
});
};
} else {
// old school shim for old browsers
module.exports = function inherits(ctor, superCtor) {
ctor.super_ = superCtor
var TempCtor = function () {}
TempCtor.prototype = superCtor.prototype
ctor.prototype = new TempCtor()
ctor.prototype.constructor = ctor
}
}
这是兼容旧浏览器的一种方式,其实主要是prototype继承以及构造函数重写罢了
可以看一下这篇文章
js继承
function Pet() {
this.type = 'pet';
}
Pet.prototype.getType = function() {
return this.type;
};
function Cat() {
Pet.apply(this, arguments); // apply super constructor
this.type = 'cat';
}
Cat.prototype = Object.create(Pet.prototype);
Cat.prototype.constructor = Cat;
var cat = new Cat;
console.log(cat.getType()); // 'cat'
console.log(cat instanceof Pet); // true
JavaScript 的类和继承
JavaScript 中没有类和继承,只有原型和对象。类是用 function 模拟的(以 function 作为构建函数),继承其实就是原型链。
ES2015 中出现了 class
和 extends
,以更简捷的语法描述了类和继承,然而实质也是通过 function 和原型链来实现的(据说是,我没验证过)
JavaScript 是一种脚本,动态语言,而 Java 是一种静态语言,所以 JavaScript 在写法上比 Java 灵活很多,不能完全的拿 Java 的思想去套 JavaScript。关于 JavaScript 对象可以任意添加属性这个问题,你可以把它想像成是一个 java.util.HashMap 对象。
这涉及到很多 JavaScript 核心的东西,需要慢慢领会。你可以在网上搜搜这方面的文章来看,比如搜 JavaScript 继承的实现,就能搜出 N 种方法来。
关于继承的实现
这个事情,我比较推荐使用 TypeScript 翻译出来的 JS,
// TypeScript
class Pet {
type;
constructor(type) {
this.type = type;
}
getPetType() {
return this.type;
}
}
class Cat extends Pet {
constructor() {
super("cat");
}
}
var cat1 = new Pet("cat");
var cat2 = new Cat();
console.log(cat1.getPetType());
console.log(cat2.getPetType());
翻译出来
// JavaScript
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var Pet = (function () {
function Pet(type) {
this.type = type;
}
Pet.prototype.getPetType = function () {
return this.type;
};
return Pet;
})();
var Cat = (function (_super) {
__extends(Cat, _super);
function Cat() {
_super.call(this, "cat");
}
return Cat;
})(Pet);
var cat1 = new Pet("cat");
var cat2 = new Cat();
console.log(cat1.getPetType());
console.log(cat2.getPetType());
// 继承函数
function classExtends(child,parent) {
var key;
for( key in parent){
if(parent.hasOwnProperty(key)){
child[key] = parent[key];
}
}
function ctor(){this.constructor = child;}
ctor.prototype = parent.prototype;
child.prototype = new ctor();
// Cat.SUPER == Pet.prototype
child.SUPER = parent.prototype;
}
function Pet(type){ this.type=type; }
// 这一句不要写在函数里面
Pet.prototype.getPetType=function(){ return this.type; }
classExtends(Cat,Pet)
function Cat(type){
Cat.SUPER.constructor.call(this,"cat");
}
var cat1 = new Cat();
console.log(cat1.getPetType());
var cat2 = new Cat();
console.log(cat2.getPetType());