JS(9)详细介绍原型和原型链

1、原型以及原型链

1.1、理解原型

  • 无论何时,只要创建一个函数,就会按照特定的规则为这个函数构建一个prototype属性,prototype属性的值是一个对象,这个对象包含了可以被该构造函数的所有实例所共享的属性和方法。在ES6中,这个对象就是通过调用构造函数创建的对象的原型

  • 当创建函数后,函数的prototype属性,指向原型对象。默认情况下,所有原型对象会自动获得一个名为constructor的属性,指回与之关联的构造函数。

  • 在自定义构造函数时,原型对象默认只会获得constructor属性,其他所有的方法都继承自Object。

  • 每次调用构造函数创建一个实例,这个实例的内部会有一个指针,即[[prototype]],这个指针指向构造函数的原型对象。脚本中没有访问这个指针的标准方式,但是在浏览器中提供了__proto__属性(在proto左右各两个下划线),通过这个属性可以访问到原型对象。

  • 因为这个不是规范的,所以最好不用,ES5中新增了Object.getPrototypeOf()的方法,可以使用这个方法来获取对象的原型

  • 通过isPrototypeOf()方法也可以检查一个对象是否位于另一个对象的原型链上

  • 通过上述我们可以理解到:实例与构造函数原型之前有直接的联系,但是实例和构造函数之间没有直接联系

  • 下面是一些例子

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

//在Person的原型上添加属性
Person.prototype.name = '张三'

//调用构造函数创建实例
let person1 = new Person()
let person2 = new Person()

//原型对象上的属性和方法被构造函数的所有实例所共享
console.log(person1.name);//'张三'
console.log(person2.name);//'张三'

//原型对象上的constructor属性指回与之关联的构造函数
console.log(Person.prototype.constructor === Person);//true

//通过__proto__属性,实例对象可以访问到原型
console.log(person1.__proto__ === Person.prototype);//true
console.log(person2.__proto__ === Person.prototype);//true
//通过Object.getPrototypeOf(),实例对象可以访问到原型
console.log(Object.getPrototypeOf(person1) === Person.prototype);//true
console.log(Object.getPrototypeOf(person2) === Person.prototype);//true

//原型对象通过isPrototypeOf(),来检查person1和person2
console.log(Person.prototype.isPrototypeOf(person1));//true
console.log(Person.prototype.isPrototypeOf(person2));//true

1.2、原型链:

  • 一个对象的原型,也可能是另外一个构造函数的实例,那么这个对象的原型又会有自己的原型。
  • 当访问一个对象的属性的时候,如果这个对象内部不存在这个属性,那么引擎就会去这个对象的原型上去找这个属性,如果还是不存在,就会去这个原型的原型上去找,就这样一直找下去。这便是原型链的概念
  • 一般来说,正常的原型链都会终止于Object的原型对象
  • Object的原型对象是null
console.log(Object.getPrototypeOf(Person.prototype)===Object.prototype);//true
console.log(Object.getPrototypeOf(Object.prototype)===null);//true

1.3、补充:constructor。

  • 上文提到,每个构造函数都是prototye属性,这个prototype属性还会自带有constructor属性指回构造函数本身,利用这一点我们可以用来判断变量数据类型
console.log((2).constructor === Number)
console.log((true).constructor === Boolean);
console.log(('帅哥'.constructor === String))
console.log(([1]).constructor === Array); // true
console.log((function() {}).constructor === Function); // true
console.log(({1:1}).constructor === Object); // true

  • 但是用constructor来判断数据类型最好还是不要用,因为有时候,如果创建一个对象来改变构造函数的原型,constructor就不能用来判断数据类型了
function Fn(){};
 
Fn.prototype = new Array();
 
var f = new Fn();
 
console.log(f.constructor===Fn);    // false
console.log(f.constructor===Array); // true
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值