关于javascript:JavaScript的原型对象的彻底理解

51次阅读

共计 2493 个字符,预计需要花费 7 分钟才能阅读完成。

前言

开篇先记住以下两点,再慢慢通过实例了解

  1. __proto__constructor 属性是 对象 所独有的;
  2. prototype属性是 函数 所独有的。

然而因为 JS 中函数也是一种对象,所以函数也领有 __proto__constructor 属性

一、函数的原型对象

咱们创立函数 A 的同时, 浏览器会在内存中创立一个对象 BA 函数默认会有一个 prototype 属性。指向了对象 B(即:prototype 的属性的值是对象 B )。​ 这个对象 B 就是函数 A 的原型对象,简称函数的原型。​ 原型对象 B 默认会有一个属性 constructor 指向了函数 A (即 constructor属性的值是函数 A )。​ 原型对象默认只有属性 constructor。其余都是从 Object 继承而来。

正式开始:举栗子探讨

// 创立一个构造函数 Foo(),并用 new 关键字实例化该构造函数失去一个实例化对象 f1。function Foo() {...};
let f1 = new Foo();

二、proto 属性

__proto__属性,它是 对象所独有的 ,能够看到__proto__ 属性都是由 一个对象指向一个对象,即指向它们的原型对象(也能够了解为父对象),那么这个属性的作用是什么呢?

它的 作用 就是当拜访一个对象的属性时,如果该对象外部不存在这个属性,那么就会去它的 __proto__ 属性所指向的那个对象(能够了解为父对象)里找,如果父对象也不存在这个属性,则持续往父对象的 __proto__ 属性所指向的那个对象(能够了解为爷爷对象)里找,如果还没找到,则持续往上找…. 直到原型链顶端 null
此时若还没找到,则返回 undefined。以上这种通过__proto__ 属性来连贯对象直到 null 的一条链即为咱们所谓的 原型链

三、prototype 属性

prototype 函数所独有的 ,它是从 一个函数指向一个对象

它的含意是 函数的原型对象,也就是这个函数所创立的实例的原型对象,由此可知:

f1.__proto__ === Foo.prototype

prototype属性的 作用

它的 作用 就是蕴含能够由特定类型的所有实例共享的属性和办法,也就是让该函数所实例化的对象们都能够找到专用的属性和办法。

四、constructor 属性

constructor属性也是 对象才领有的 ,它是从 一个对象指向一个函数 ,含意就是 指向该对象的构造函数 ,每个对象都有构造函数,从图中能够看出**Function** 这个对象比拟非凡,它的构造函数就是它本人(因为 Function 能够看成是一个函数,也能够是一个对象),所有函数最终都是由 Function() 构造函数得来,所以constructor 属性的起点就是 Function()
举例子

// 创立构造函数
function Person () {}

// 应用 Person.prototype 间接拜访到原型对象
// 给 Person 函数的原型对象中增加一个属性 name,值是 "张三"
    Person.prototype.name = "张三";

// 创立一个实例 p1
var p1 = new Person();
// 拜访 p1 对象的属性 name,尽管在 p1 对象中咱们并没有明确的增加属性 name,然而 p1 的 prototype 属性指向的原型中有 name 属性,所以这个中央能够拜访到属性 name 值。alert(p1.name);  // 张三
var p2 = new Person();
        alert(p2.name);  // 张三  都是从原型中找到的,所以一样。alert(p1.name === p2.name);  // true

// 因为不能批改原型中的值,上面这种办法就间接在 p1 中增加了一个新的属性 name,而后在 p1 中无奈再拜访到原型中的属性。p1.name = "李四";
        alert("p1:" + p1.name);
// 对 p2 来说依然是拜访的原型中的属性。alert("p2:" + p2.name);  // 张三  
// 如何证实证实 p1.__proto__ 与 Person.prototype 是雷同的
        alert(p1.__proto__ === Person.prototype);   //true

五、罕用办法

hasOwnProperty()in操作符

作用:判断函数的原型所在位置

function Person () {};
Person.prototype.name = "志玲";
var p1 = new Person();
p1.sex = "女";

// 定义一个函数去判断原型所在的地位
function propertyLocation(obj, prop){if(!(prop in obj)){alert(prop + "属性不存在");
    }else if(obj.hasOwnProperty(prop)){alert(prop + "属性存在于对象中");
    }else {alert(prop + "对象存在于原型中");
    }
}
propertyLocation(p1, "age");   //age 属性不存在
propertyLocation(p1, "name");  //name 对象存在于原型中
propertyLocation(p1, "sex");   //sex 属性存在于对象中

六、动静原型模式创建对象

// 构造方法外部封装属性
function Person(name, age) {
  // 每个对象都增加本人的属性
  this.name = name;
  this.age = age;
  /*
      判断 this.eat 这个属性是不是 function,如果不是 function 则证实是第一次创建对象,则把这个 funcion 增加到原型中。如果是 function,则代表原型中曾经有了这个办法,则不须要再增加。perfect!完满解决了性能和代码的封装问题。*/
  if(typeof this.eat !== "function"){Person.prototype.eat = function () {alert(this.name + "在吃");
      }
  }
}
var p1 = new Person("志玲", 40);
p1.eat(); // 志玲 在吃

作者:炒面熊
链接:https://juejin.im/post/6894157108904722439
起源:掘金

正文完
 0