资讯专栏INFORMATION COLUMN

js 的原型 原型链 原型链的继承

soasme / 1345人阅读

摘要:图片描述缺点是无法实现多继承可以在构造函数中,为实例添加实例属性。

对象的方法
Object.assign()
对象可以简写 ,如果 key 和 value 相等则可以简写
let name = "xm";
let age = 2;
let obj = {
    name,
    age,
    fn(){ // 可以省略函数关键字和冒号:
        console.log(22);
    }
}
对象新增的方法 Object.setPrototypeOf()

let o2 = {
    age: 22,
    name: "mazz"
}
let o1 = {
    name: "zz",
    __proto__: o2
    getO2Name(){
        return super.name
    }
}
// __proto__ 每一个对象上都有这个东西,如果自己家找不到 会通过这个链向上找
Object.setPrototypeOf(o1,o2); // 通过这个方法 把 o1 的链指向 o2
// super 在子对象中指向的是 __proto__对应的内容
// 等价于 o1.__proto__= o2;
console.log(o1.age); // 22
console.log(o1.getO2Name())
class
js 没有类的概念,js的继承是通过 prototype 实现的,每个构造函数上都有一个 prototype 属性,指向他的原型对象,原型对象上的 constructor 指向了构造函数 ,构造函数实例化后有一个proto 指向原型对象 原型对象的 constructor 指向构造函数 就实现了 继承

1.原型链是怎么实现继承的?
2.可以围绕构造函数说一下的?
3.构造函数实例化后是怎么继承构造函数的属性
4.怎么向原型对象上添加属性

function Person (){} //声明一个函数 js中 函数是对象 也是构造函数
console.log(Person.prototype); // Person 对象的原型
// 由此打印出来的结果 可以看出 Person对象的原型上有 一个constructor 属性, 它指向 Person 的构造函数 也就是Person本身 还有一个__proto__属性
 function Person(name) {
     this.name = name; // 私有的
 }
 Person.prototype.eating = function() {//给对象的原型对象上添加一个eating 的方法 ,new 出来的实例 都会共享此方法的
     console.log("eat food")
 }
 Person.prototype.age = 12;// 给对象的原型对象上 添加一个age 属性
    var p1 = new Person("blob");
   var p2 = new Person("lisa");
console.log(p1.age,p2.age); // 12,12
console.log(p1.eating(),p2.eating()); // eat food eat food
![图片描述][1]
// 所以只要是Person的对象 他们都会共享原型对象上的方法和属性的
**WHY?? 这个实例 能够访问 原型对象上的方法及属性的 **
  //其实 p1 的实例上有一个指针,这个指针指向 构造函数的原型对象(通俗点 也就是所属类的原型)此时原型对象中的方法及属性自然也就能访问到的

总结下 构造函数 原型 和实例的关系:

每一个构造函数都有一个原型对象(prototype) 原型对象上 拥有一个指向构造函数的指针(constructor)

实例上拥有一个指向原型对象的指针 即 proto

类 以前就是构造函数 分为私有和公有

 function Parent () {
    this.name = "maz"; // 当前parent的私有的属性 实例上自己调用的
  }
// new 出来的实例可以调用原型上的方法
Parent.prototype.coding = function(){  // 公有的 别人继承了 都可以用的
    console.log("有思想的coding");
}

function Child () {
}

Child.prototype = new Parent() // 核心 主要就是 子类的原型指向 父类的实例
let c = new Child();
console.log(c.constructor); // Parent
console.log(c.name,c.coding()); //拿到 公有方法和私有属性

原型链继承的一种基本模式 其原理就是 对象的实例 拥有一个指向原型对象的指针(指向所属类的原型)Child 的 原型对象拥有了 Parent 的实例后,自然也拥有了一个指向 Parent 原型对象的指针了。此时 我们 new 一个 Child 的实例 c 时,c 实例包含着一个指向Child 原型的指针, Child.prototype 拥有一个指向 Parent 原型对象的指针,Parent 原型本身包含着一个指向自身构造函数的指针,这样一来,就构成了实例与原型的链条,也就是所谓的原型链的概念了
**注意**:这里的c对象的 constructor 现在指向了 Parent 了,因为 Child 的原型指向了 另外一个对象 Parent 的原型,而这个原型对象的 constructor 指向的是 Parent。
![图片描述][2]


缺点是:
1. 无法实现多继承
2. 可以在Child 构造函数中,为Child实例添加实例属性 。如果要新增 原型属性或者方法的话 则必须放在 new Child() 实例化之后执行。
3.来自原型对象的所有属性被所有的实例共享
4.创建子类实例时,无法向父类构造函数传参

// 一般就不用 上面 这种方式了
// Object.Create()  // 只是继承公有方法
Parent.fn = funciton (){ //属于Parent 类上的私有属性

}
![图片描述][3]
function create(parentProto,param){
    function Fn(){} // 相当于构建一个类 类的原型链指向了父类的原型
    Fn.prototype = parentProto;
    let fn = new Fn();
    fn.constructor = param.constructor.value; // 手动改变constructor的指向
    return fn;
}
// 子类查找时 可以查到父类的原型,所以可以拿到父类的公共方法
Child.prototype =create(Parent.prototype);
let child = new Child();
console.log(child.coding())
console.log(child.constructor);// Parent
**希望这里的constructor是Child 怎么实现呢?**
Child.prototype =create(Parent.prototype,{constructor:{ value: Child }})
let child = new Child;
console.log(child.constructor);// Child
//静态属性 是可以继承的
Child.__proto__ = Parent;
Child.fn();

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/105814.html

相关文章

  • JS面向对象程序设计之继承实现 - 原型注意点

    摘要:第一种方式是使用操作符,只要检测的实例对象中的原型链包含出现过的构造函数,结果就会返回。而这也正是组合使用原型模式和构造函数模式的原因。在构造函数模式中定义属性,在原型模式中定义共享的方法。 前言:最近在细读Javascript高级程序设计,对于我而言,中文版,书中很多地方翻译的差强人意,所以用自己所理解的,尝试解读下。如有纰漏或错误,会非常感谢您的指出。文中绝大部分内容引用自《Ja...

    pf_miles 评论0 收藏0
  • 如何理解JavaScript原型原型

    摘要:之前有朋友问怎么去理解原型和原型链的问题。理解原型链的小技巧将箭头视作泛化子类到父类关系那么图中所有的虚线将构成一个继承层级,而实线表示属性引用。原型链是实现继承的重要方式,原型链的形成是真正是靠而非。 之前有朋友问怎么去理解原型和原型链的问题。这个问题,在面试中,很多同学经常都会遇到。这里给大家讲讲,方便大家记忆。 JavaScript的特点JavaScript是一门直译式脚本...

    xuexiangjys 评论0 收藏0
  • 如何理解JavaScript原型原型

    摘要:之前有朋友问怎么去理解原型和原型链的问题。理解原型链的小技巧将箭头视作泛化子类到父类关系那么图中所有的虚线将构成一个继承层级,而实线表示属性引用。原型链是实现继承的重要方式,原型链的形成是真正是靠而非。 之前有朋友问怎么去理解原型和原型链的问题。这个问题,在面试中,很多同学经常都会遇到。这里给大家讲讲,方便大家记忆。 JavaScript的特点JavaScript是一门直译式脚本...

    adie 评论0 收藏0
  • JS面向对象程序设计之继承实现 - 原型

    摘要:简单回顾一下构造函数原型和实例对象之间的关系每个构造函数都有一个原型对象。找到生成构造函数的原型对象的构造函数,搜索其原型对象,找到了。 JS面向对象的程序设计之继承的实现 - 原型链 前言:最近在细读Javascript高级程序设计,对于我而言,中文版,书中很多地方翻译的差强人意,所以用自己所理解的,尝试解读下。如有纰漏或错误,会非常感谢您的指出。文中绝大部分内容引用自《JavaS...

    zhaochunqi 评论0 收藏0
  • 理解js原型继承

    摘要:相当于在用原型继承编写复杂代码前理解原型继承模型十分重要。同时,还要清楚代码中原型链的长度,并在必要时结束原型链,以避免可能存在的性能问题。 js是一门动态语言,js没有类的概念,ES6 新增了class 关键字,但只是语法糖,JavaScript 仍旧是基于原型。 至于继承,js的继承与java这种传统的继承不一样.js是基于原型链的继承. 在javascript里面,每个对象都有一...

    wthee 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<