这篇文章主要为大家展示了“js中继承方法有哪些”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“js中继承方法有哪些”这篇文章吧。
js的原型继承 -- prototype
先说下什么是prorotype?
js中,俗话说“一切皆对象”。用new 出来的都是函数对象;否则就是普通对象
函数对象都有prototype(原型对象);而普通对象则只有__proto__(原型指针)
函数对象的一个特点:可以实现不同类之间的方法继承
函数的子类可以共享父类的方法,而父类不能想用子类的方法
eg: (prototype的继承)
//创建父类函数对象
function Personal(name, age) {
this.name = name; //父类的私有属性
this.age = age;
this.house = ['北京', '上海']
}
Personal.prototype.run = function() { //给父类原型动态添加方法
alert('原型方法:' + this.name + ' is running!');
}
var per = new Personal('小白', 24)
per.run() //打印 --> 原型方法:小白 is running!
//创建子类函数对象
function Boy() {}
Boy.prototype = new Personal('小黑', 19) //子类继承父类的所有属性和方法
Boy.prototype.source = 100 //给子类添加原型属性
Boy.prototype.printSource = function() { //给子类添加方法
alert(this.name + '的原型方法printSouce打印成绩为:' + this.source) //小黑的原型方法printSouce打印成绩为:100
}
Boy.prototype.run() //打印 --> 原型方法:小黑 is running!
var boys = new Boy()
boys.printSource()
console.log(boys, '--boys---') //打印 -->19, 小黑, 100 (这里会沿着prototype向上查找到Personal的属性)
以下是关于prototype继承需要注意的点:
1.如果父类中有引用类型的属性:Array,Object等。子类继承了这些属性,并尝试改变的话,会影响到父类的属性。
//创建另外一个实例1:
var boys1 = new Boy()
boys1.house.push('深圳')
//打印这两个实例:
console.log(boys, boys1)
可以看出来,当属性为引用类型时,只要有一个实例的属性做了操作,所有的实例都会受到影响。
2.该方式导致 Boy.prototype.constructor 被重写,它指向的是 Personal 而非 Boy。因此你需要手动将 Boy.prototype.constructor 指回 Boy。
Boy.prototype = new Personal();
Boy.prototype.constructor === Personal; // true
// 重写 Boy.prototype 中的 constructor 属性,指向自己的构造函数 Boy
Boy.prototype.constructor = Boy;
3.因为 Boy.prototype = new Personal(); 重写了 Boy 的原型对象,所以 printSource 放在重写原型对象之前会被覆盖掉,因此给子类添加原型方法必须在替换原型之后(eg是没有被覆盖的)。
function Boy() {}
Boy.prototype = new Personal();
// 给子类添加原型方法必须在替换原型之后
Boy.prototype.printSource = function() {
console.log('printSource~');
};
4.创建 boys 实例时无法向父类的构造函数传参,也就是无法初始化 source属性。因此:只能创建实例之后再修改父类的属性。
const boys = new Boy();
// 只能创建实例之后再修改父类的属性
boys.source = 100;
apply()、call()方法的继承
了解下apply()、call()方法
1.apply()、call()的用法:
obj.call(thisObj, arg1, arg2, ...);
obj.apply(thisObj, [arg1, arg2, ...]);
obj是父级,thisObj是子级;第二个参数apply可以接收一个数组,而call只能是每项逐个接收。
2.apply和call 本来就是为了扩展函数的作用域而生的,换句话说就是为了改变this的指向存在的。
3.当一个object没有某种方法,但是其他的有,我们可以借助call和apply来用其他对象的方法来做操作,也可以传参数。
//eg:
function Personal(name, sex) {
this.name = name;
this.sex = sex;
this.say = function (){
alert('姓名:' + this.name + ';性别:' + this.sex)
}
}
const per = new Personal('Allan', '男')
per.say();
//apply()方法实现:
function Girls(name, sex) {
Personal.apply(this, [name, sex]);
//Person.apply(this,arguments); //跟上句一样的效果,arguments
//Print.apply(this,arguments); //还可以实现继承多个父类,但是原型 prototype只能继承一个父类!!!切记
}
const girls1 = new Girls('Lucy', '女')
girls1.say();
//call()实现:
function Boy(name, sex) {
Personal.call(this, name, sex);
}
const boys = new Boy('Barry', '男');
boys.say() //
总结:
prototype可以动态的给对象增加属性和方法。
可以实现子类继承父类,拥有父类的属性和方法。
call和apply的区别,在于参数的不同。
call和apply,理解为在子类的运行环境中执行父类的方法和属性。
call和apply可以实现一个子类继承多个父类,但是prototype只能有一个父类。
以上是“js中继承方法有哪些”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。