《原型链重置版》一万多字让你读懂JavaScript原型对象与原型链的继承,探秘属性的查找机制! (5)

简介: 更多javascript继承实现的方式

logo.png

另类继承实现方法

修改构造函数this指向从而实现继承

我们有时候可以借助call方法来实现简单的继承效果!

举个栗子

function Animal(name,age,food){
   
   
    this.username=name;
    this.age=age;
    this.eat=function (){
   
   
        console.log('这只['+this.username+']动物要吃['+food+']');
    }
}


Animal.prototype.color='黑色';
Animal.prototype.say=function (){
   
   
    console.log('我的名字叫'+this.name);
}

function Panda(name,age,eat){
   
   
    this.like='玩耍';
    Animal.call(this,name,age,eat); //借用一下
}

var p1=new Panda('熊猫盼盼',18,'竹叶');

//打印输出
console.log(p1);
p1.eat();

结果

11-0-2.png
)

这个案例中,应用了call修改this指向来达到一个共享的目的!

但是这种使用call等方法来修改this严格意义上来讲,只能算借用!

因为这种方式有一个很大的缺点,就是不能继承所谓父类原型里面的属性方法,不然你看上图,打印的结果当中并没有出现Animal类原型对象中的color属性say方法

所以这种继承方式如何和prototype修改原型方式结合一起使用就会有意想不到的效果,并且参数的传递也会更加灵活多变!

举个栗子

//定义构造函数
function Person(userename,age,sex){
   
   
    this.name=userename;
    this.age=age;
    this.sex=sex;
    this.type='人类';
}
Person.prototype.say=function(){
   
   
    console.log("hello world");
}

function Student(username,age,sex,score){
   
   
    //借用Person构造函数
    Person.call(this,username,age,sex);
    //定义属性
    this.score=score
}

//改变原型指向
Student.prototype=new Person();//不传值
Student.prototype.behavior=function(){
   
   
    console.log("英语学习!!");
}


var s1=new Student("张三",15,"男","100分")

//打印结果看看
console.log(s1);
console.log(s1.type);
console.log(s1.name);
console.log(s1.age);
console.log(s1.sex);
console.log('考试得分:'+s1.score);

s1.behavior();
s1.say();

代码分析

从上面的代码中,我们可以看到构造函数Student中我们借用了Person构造函数, 然后在通过prototype修改原型指向,这样一来,不仅可以获取到父类构造函数中的属性和方法 也可以获取到父类原型对象中的属性和方法

这时都可以通过__proto__这个链条拿到!

如图

11-0-3.png

通过循环复制实现继承

我们的原型对象prototype既然是一个对象,那么我们也可以通过循环复制的手法把父级原型对象里面的属性和方法拷贝到目标原型对象下,同时也可以结合call方法借用构造函数中的属性和方法

代码如下

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

Person.prototype.type = "人类";
Person.prototype.nationality = "中国";
Person.prototype.job = '软件开发';
Person.prototype.like = '足球,篮球,游戏';
Person.prototype.test = 123;


function Student(username,age) {
   
   
    Person.call(this,username,age);
}

var per = Person.prototype;
var stu = Student.prototype;


//过滤不需要的属性
var arr=['type','nationality','test'];
for (k in per) {
   
   
    if(arr.indexOf(k)==-1){
   
   
        stu[k] = per[k];
    }
}

var s1=new Student('李四',18);
var s2=new Student('王五',25);

console.log(s1);
console.log(s2);

如图

11-0-4.png

__proto__的兼容性

根据MDN官方的建议,其实__proto__是被弃用了的!

那么到底我们平常使用什么来修改原型的指针呢?

JavaScript 中,你的确是可以通过直接修改实例对象__proto__ 属性来达到目的!

__proto__ 是一个非标准的属性,它在大多数的js环境中都可以使用,包括浏览器Node.js 但是由于这个属性是非标准的,它在一些环境中可能不可用,或者在未来的标准中可能会被弃用,也就是说虽然一些浏览器仍然支持__proto__,但也许已从相关的web标准中移除,也许正准备移除或者出于兼容性而保留!

__proto__浏览器兼容性如下表

11-1.png

所以如果可以的话我们尽量不使用__proto__而改成其他,例如:Object.setPrototypeOf方法

举个栗子

让我们使用Object.setPrototypeOf来实现一个简单的继承

代码如下

function Test(){
   
   

}

Test.prototype.company='重庆科技';

function Test2(){
   
   

}

Test2.prototype.num=100;


function Test3(){
   
   

}

Test3.prototype.username='张三';

//实现继承
Object.setPrototypeOf(Test2.prototype, Test.prototype);
Object.setPrototypeOf(Test3.prototype, Test2.prototype);

var t3=new Test3();
console.log(t3);

效果

11-2.png

再看一个案例!

const a = {
   
    company : '重庆科技' };
const b = {
   
    age: 33 };
const c = {
   
    username: "张三" };

//实现继承
Object.setPrototypeOf(a, b);
Object.setPrototypeOf(b, c);

console.log(a);
console.log(a.username);
console.log(a.age);
console.log(a.company);

效果如下

11-3.png

所以我觉得可以的情况下,尽量使用标准的Object.setPrototypeOf方法来实现继承

因为Object.setPrototypeOf方法基本上被所有现代浏览器引擎所支持, 并且也允许动态地修改对象的原型

相关文章
|
1月前
|
JavaScript 前端开发
如何在 JavaScript 中使用 __proto__ 实现对象的继承?
使用`__proto__`实现对象继承时需要注意原型链的完整性和属性方法的正确继承,避免出现意外的行为和错误。同时,在现代JavaScript中,也可以使用`class`和`extends`关键字来实现更简洁和直观的继承语法,但理解基于`__proto__`的继承方式对于深入理解JavaScript的面向对象编程和原型链机制仍然具有重要意义。
|
1月前
|
JSON 前端开发 JavaScript
JavaScript中对象的数据拷贝
本文介绍了JavaScript中对象数据拷贝的问题及解决方案。作者首先解释了对象赋值时地址共享导致的值同步变化现象,随后提供了五种解决方法:手动复制、`Object.assign`、扩展运算符、`JSON.stringify`与`JSON.parse`组合以及自定义深拷贝函数。每种方法都有其适用场景和局限性,文章最后鼓励读者关注作者以获取更多前端知识分享。
18 1
JavaScript中对象的数据拷贝
|
1月前
|
JavaScript 安全 中间件
深入浅出Node.js中间件机制
【10月更文挑战第36天】在探索Node.js的奥秘之旅中,中间件的概念如同魔法一般,它让复杂的请求处理变得优雅而高效。本文将带你领略这一机制的魅力,从概念到实践,一步步揭示如何利用中间件简化和增强你的应用。
|
1月前
|
JavaScript 前端开发
JavaScript 原型链的实现原理是什么?
JavaScript 原型链的实现原理是通过构造函数的`prototype`属性、对象的`__proto__`属性以及属性查找机制等相互配合,构建了一个从对象到`Object.prototype`的链式结构,实现了对象之间的继承、属性共享和动态扩展等功能,为 JavaScript 的面向对象编程提供了强大的支持。
|
1月前
|
JavaScript 前端开发
原型链在 JavaScript 中的作用是什么?
原型链是 JavaScript 中实现面向对象编程的重要机制之一,它为代码的组织、复用、扩展和多态性提供了强大的支持,使得 JavaScript 能够以简洁而灵活的方式构建复杂的应用程序。深入理解和熟练运用原型链,对于提升 JavaScript 编程能力和开发高质量的应用具有重要意义。
|
1月前
|
JavaScript 前端开发
如何使用原型链继承实现 JavaScript 继承?
【10月更文挑战第22天】使用原型链继承可以实现JavaScript中的继承关系,但需要注意其共享性、查找效率以及参数传递等问题,根据具体的应用场景合理地选择和使用继承方式,以满足代码的复用性和可维护性要求。
|
1月前
|
JavaScript 前端开发 开发者
js实现继承怎么实现
【10月更文挑战第26天】每种方式都有其优缺点和适用场景,开发者可以根据具体的需求和项目情况选择合适的继承方式来实现代码的复用和扩展。
31 1
|
27天前
|
Web App开发 JSON JavaScript
Node.js 中的中间件机制与 Express 应用
Node.js 中的中间件机制与 Express 应用
|
1月前
|
JavaScript 前端开发
JavaScript中的原型 保姆级文章一文搞懂
本文详细解析了JavaScript中的原型概念,从构造函数、原型对象、`__proto__`属性、`constructor`属性到原型链,层层递进地解释了JavaScript如何通过原型实现继承机制。适合初学者深入理解JS面向对象编程的核心原理。
25 1
JavaScript中的原型 保姆级文章一文搞懂
|
5月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
103 2
下一篇
DataWorks