博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
重新认识javascript对象(三)——原型及原型链
阅读量:6419 次
发布时间:2019-06-23

本文共 3368 字,大约阅读时间需要 11 分钟。

一、原型检测

javascript中提供Object.getPrototypeOf()方法来获得对象的直接原型。

function Person() {    this.name = 'sillywa'}var person1 = new Person()Object.getPrototypeOf(person1)  // {constructor: ƒ Person()}Object.getPrototypeOf(person1.__proto__)  // Object.prototypevar person = {    name: 'sillywa'}var person2 = Object.create(person)Object.getPrototypeOf(person2)  // {name: "sillywa"}复制代码

javascript有以下几种方法检测一个对象的原型:

  1. isPrototypeOf():检测一个对象是否是另一个对象的原型
  2. obj.constructor.prototype:检测非Object.create()创建的对象的原型
var obj1 = {    name: 'sillywa'}var obj2 = Object.create(obj1)// isPrototypeOf()方法Object.prototype.isPrototypeOf(obj1)  // trueobj1.isPrototypeOf(obj2)  // trueObject.prototype.isPrototypeOf(obj2)  // true// obj.constructor.prototypeobj1.constructor.prototype === Object.prototype  // true// obj1是obj2的原型,以下等式应为trueobj2.constructor.prototype === obj1  // false// 而实际上obj2.constructor.prototype === Object.prototype  // true复制代码

以上代码中obj1obj2的原型,obj2.constructor.prototype === obj1应为true但是实际上却是false,因为obj2__proto__里面并没有一个constructor属性,obj2.constructor实际上是obj1__proto__里面的constructor,所以obj2.constructor.prototype === Object.prototype

一、constructor__proto__prototype之间的关系

在javascript中我们每创建一个对象,该对象都会获得一个__proto__属性(该属性是个对象),该属性指向创建该对象的构造函数的原型prototype,同时__proto__对象有一个constructor属性指向该构造函数。这里我们需要注意的是只有函数才有prototype,每个对象(函数也是对象)都有__proto__Object本身是个构造函数。举例来说:

var obj = new Object()// 也可以使用对象字面量创建,但使用Object.create()情况会不一样// Object本身是个构造函数Object instanceof Function  // trueobj.__proto__ === Object.prototype  // trueobj.__proto__.constructor === Object  // true// 我们一般习惯这样写obj.constructor === Object  // true复制代码

当我们访问obj.constructor的时候,obj本身是没有constructor属性的,但属性访问会沿着__proto__向上查找,即在obj.__proto__里面寻找constructor属性,如果找到了就返回值,如果未找到则继续向上查找直到obj.__proto__.__proto__...(__proto__) === null为止,没有找到则返回undefined。这样由__proto__构成的一条查找属性的线称为‘原型链’。

二、进一步探讨

我们知道JS是单继承的,Object.prototype是原型链的顶端,所有对象从它继承了包括toString等等方法和属性。

前面我们说到Object本身是构造函数,那么它继承了Function.prototype;Function也是对象,继承了Object.prototype。这里就有一个鸡和蛋的问题:

Object instanceof Function  // trueFunction instanceof Object  // true复制代码

以下是ES规范的解释:

Function本身就是函数,Function.__proto__是标准的内置对象Function.prototypeFunction.prototype.__proto__是标准的内置对象Object.prototype

function Person(name) {    this.name = name}var person1 = new Person('sillywa')复制代码

总的来说:先有Object.prototype(原型链顶端),Function.prototype继承Object.prototype而产生,最后,FunctionObject和其它构造函数继承Function.prototype而产生。

三、Object.create()

我们知道通过Object.create()创建的对象实际上等于将该对象的__proto__指向Object.create()里面的参数对象,那么当涉及到原型时它是怎么工作的呢?

var a = {    name: 'sillywa'}var b = Object.create(a)b.__proto__ === Object.prototype  // falseb.__proto__ === a  // trueb.__proto__.constructor === Object  // trueb.__proto__.hasOwnProperty('constructor')  // false复制代码

下面我们来具体看一看当var b = Object.create(a)到底发生了什么,以下实在浏览器中的结果:

我们可以看到当
var b = Object.create(a)实际上是把
b
__proto__指向了
a。当访问
b.constructor时,实际上访问的是
b.__proto__.__proto__.constructor

四、实例与总结

function Person(name) {    this.name = name}var person1 = new Person('sillywa')person1.__proto__ === Person.prototypeperson1.__proto__.__proto__ === Person.prototype.__proto__person1.__proto__.__proto__ === Object.prototypePerson.prototype.__proto__ === Object.prototype person1.__proto__.__proto__.__proto__ === nullPerson.__proto__ === Function.prototype复制代码

以上均返回true,前五个等式和第一部分内容相关,最后一个等式为第二部分内容,需要注意的是IE浏览器里面并没有实现__proto__,为了便于理解我们可以这样解释,但是最好不要在实际中使用

转载地址:http://zxlra.baihongyu.com/

你可能感兴趣的文章
C指针练习
查看>>
web项目buildPath与lib的区别
查看>>
php对redis的set(集合)操作
查看>>
我的友情链接
查看>>
ifconfig:command not found的解决方法
查看>>
计算机是怎么存储数字的
查看>>
Codeforces Round #369 (Div. 2) A. Bus to Udayland 水题
查看>>
adb上使用cp/mv命令的替代方法(failed on '***' - Cross-device link解决方法)
查看>>
C++标准库简介、与STL的关系。
查看>>
Spring Boot 3 Hibernate
查看>>
查询EBS请求日志的位置和名称
查看>>
大型机、小型机、x86服务器的区别
查看>>
J2EE十三个规范小结
查看>>
算法(第四版)C#题解——2.1
查看>>
网关支付、银联代扣通道、快捷支付、银行卡支付分别是怎么样进行支付的?...
查看>>
大数据开发实战:Stream SQL实时开发一
查看>>
C++返回引用的函数例程
查看>>
dll 问题 (转)
查看>>
使用sql生成UUID
查看>>
REST API用得也痛苦
查看>>