设为首页 加入收藏

TOP

原来你是这样的---原型和原型链(二)
2019-09-17 19:09:58 】 浏览:116
Tags:原来 这样 --- 原型
ovincePerson原型里面的方法eat-->标签:" + this.name + ", 地方小吃是:" + this.feature + ", hero: " + this.hero + ", skin: " + this.skin); } //重写从父级原型继承下来的方法 ProvincePerson.prototype.write = function(){ console.log("ProvincePerson原型里面重写从父级原型继承的write方法-->。。。。^_^"); } View Code

 

  结合以上代码,绘制构造函数原型链关系,如下图:

  

对上图进行说明,和原型链知识点进行归纳:

  • ProvincePerson、ChinaPerson、Person三个是自定义构造函数,Function、Object两个是系统构造函数;
  • 原型链方向(寻找父级方向)为:ProvincePerson --> ChinaPerson --> Person --> Object --> null ;   Function -->  Object --> null ;
  • 上图中obj是构造函数ProvincePerson的实例对象;矩形代表构造函数六边形代表构造函数的原型对象红色虚线代表实例对象通过其私有原型属性__proto__寻找父级原型走向;
  • prototype是构造函数的属性,__proto__是构造函数的实例对象的属性
    • 实例对象的__proto__属性指向该对象的构造函数的prototype属性,即 实例对象.__proto__ = 构造函数.prototype ; 
    • __proto__是隐式原型,平常不建议直接使用,通常用Object.getPrototypeOf(对象)来获取实例对象的原型;
    • 构造函数的prototype 和 实例对象的__proto__ 都是对象
  • 敲重点了:
    • 函数调用时,使用new关键字,叫构造函数,比如var obj = new ProvincePerson() 。这时ProvincePerson叫构造函数,是一个类模板;
    • 当函数不使用new关键字,直接调用时,就是一个普通函数,比如ProvincePerson()、Object()、Function() 等等,这样使用它们都叫普通函数;
    • 所有的普通函数都是构造函数Function的实例对象,比如Object、Function作为普通函数调用时它们都是Function的实例对象。
    • 这就是为什么函数既有prototype属性,也有__proto__属性,因为它们都有双重身份:
    • 第一重身份是它们有可能会使用new关键字,这时它们是构造函数,有prototype属性;
    • 第二重身份是它们不使用new关键字,直接调用,这时候它们都是构造函数Function的实例对象,所以这时候它们有__proto__属性。
    • Function作为一个特殊的存在,特殊之处在于 Function.prototype = Function.__proto__ ,即它作为构造函数的原型(prototype) 和 它作为普通函数的实例对象的原型(__proto__) 指向同一个对象;
  • 构造函数的原型的constructor属性指向构造函数,实例对象的constructor也指向构造函数,即 构造函数.prototype.constructor = 构造函数  = 该构造函数的实例对象.constructor 
  • 一个构造函数继承自父级构造函数,会拥有父级所有对外的,包括构造函数的属性和方方法,和父级原型的属性和方法;
  • 子级构造函数可以对继承的属性和方法进行重写;如果构造函数里面的方法或属性,和它的原型上的方法或属性同名,则调用时优先构造函数里面的方法或属性;
  • 所有的对象或构造函数通过原型链,追本溯源,最后的老祖宗都是Object。即所有的构造函数都是Object的子级或间接子级。Object的原型的原型是null,到这里就是终极大结局了!

 

  大概知识点就是这些,在上面代码的基础上,再来一些测试代码,验证一下。先上一份测试原型链关系的代码:

//测试一下
var pro1 = Person.prototype, pro2 = ChinaPerson.prototype, pro3 = ProvincePerson.prototype;
//ProvincePerson原型的原型 === ChinaPerson的原型
var pro3_china = Object.getPrototypeOf(pro3);

//ProvincePerson原型的原型的原型 === Person的原型
var pro3_person = Object.getPrototypeOf(pro3_china);

//ProvincePerson原型的原型的原型的原型 === Object的原型
var pro3_object = Object.getPrototypeOf(pro3_person);

//Function和Object作为普通函数时是构造函数Function的实例对象,获取这两个实例对象的原型
var pro_function = Object.getPrototypeOf(Function), pro_object = Object.getPrototypeOf(Object);

console.log("************* 原型链测试 start **********")
console.log("构造函数ProvincePerson继承自ChinaPerson, 构造函数ChinaPerson继承自Person, Person继承自Object")
console.log("Object --> Person --> ChinaPerson --> ProvincePerson")
console.log("Person.原型:", pro1);
console.log("ChinaPerson.原型:", pro2);
console.log("ProvincePerson.原型:", pro3);
console.log("ProvincePerson.原型.原型: ", pro3_china);
console.log("ProvincePerson.原型.原型.原型: ", pro3_person);
console.log("ProvincePerson.原型.原型.原型.原型:", pro3_object);
console.log("ProvincePerson.原型.原型 === ChinaPerson.原型 --> ", pro3_china === pro2);
console
首页 上一页 1 2 3 4 下一页 尾页 2/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇antd Bug记录 下一篇模块化开发

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目