原型链是什么,有什么用处?若想访问一个对象的原型,应该使用什么方法?

1 背景介绍

1.1什么是原型

学习原型链之前我们首先要明白什么是原型;那么什么是原型呢?我们来简单学习一下:

只要我们像这样简单的定义一个函数foo(),就可以访问像访问其他对象一样访问该函数的属性:

>>>function foo(a,b){return a*b;}

>>>foo.length

2

>>>foo.constructor

Function()

其实我们在创建一个函数的时候,这个函数就包括了prototype属性,它的初始值是一个空对象(object),

>>>typeof foo.prototype

"object"

所以我们可以自己在这个空对象中添加属性,像这样:

>>>foo.prototype = {}

1.2 原型有什么作用

        简述一下prototype属性的出现:

        第一版浏览器无用户交互—》需要脚本语言—》借鉴C++和Java语言,又想节省服务器资源和时间—》prototype。

         由于所有的实例对象共享同一个prototype对象,那么从外界看起来,prototype对象就好像是实例对象的原型,而实例对象则好像"继承"了prototype对象一样。

          这个属性包含一个对象(以下简称"prototype对象"),所有实例对象需要共享的属性和方法,都放在这个对象里面;那些不需要共享的属性和方法,就放在构造函数里面。

        而实例对象一旦创建,将自动引用prototype对象的属性和方法。也就是说,实例对象的属性和方法,分成两种,一种是本地的,另一种是引用的。

2 知识剖析

2.1 原型链是什么

        我们上面说到,每个构造函数在创建时都包含一个属性prototype,其初始值是一个空对象;

 

原型链(图片来源与网络)

原型对象结构:

Function.prototype={ 

 constructor :Function,

__proto__:parentprototype,

someprototypeproperties: ... 

 };

       函数的原型对象constructor默认指向函数本身,原型对象除了有原型属性外,为了实现继承,还有一个原型链指针__proto__,该指针指向上一层的原型对象,而上一层的原型对象的结构依然类似,这样利用__proto__一直指向Object的原型对象上,而Object的原型对象用Object.prototype.__proto__ = null表示原型链的最顶端,如此变形成了javascript的原型链继承,同时也解释了为什么所有的javascript对象都具有Object的基本方法。

 

 

 

 

3 常见问题

Array.isArray(Array.prototype)输出什么?

4 解决方案

Array.prototype是Array构造函数实例的原型,构造函数实例化后仍为数组,所以输出true。

5 编码实战

6 扩展思考

 

7 参考文献

参考一:Javascript继承机制的设计思想

参考二:《JavaScript面向对象编程指南》

参考三:JavaScript 世界万物诞生记

参考三:JavaScript.The Core(推荐)

8 更多讨论

Q1:  prototype与_proto_是什么关系?

__proto__(隐式原型)、prototype(显式原型)

A1:   显式原型 explicit prototype property:每一个函数在创建之后都会拥有一个名为prototype的属性,这个属性指向函数的原型对象。

隐式原型 implicit prototype link:JavaScript中任意对象都有一个内置属性[[prototype]],在ES5之前没有标准的方法访问这个内置属性,但是大多数浏览器都支持通过__proto__来访问。ES5中有了对于这个内置属性标准的Get方法Object.getPrototypeOf().

Q2:若想访问一个对象的原型,应该使用什么方法?

获取实例对象obj的原型对象,有三种方法

1. obj.__proto__

2. obj.constructor.prototype

3. Object.getPrototypeOf(obj)

上面三种方法之中,前两种都不是很可靠。最新的ES6标准规定,__proto__属性只有浏览器才需要部署,其他环境可以不部署。而obj.constructor.prototype在手动改变原型对象时,可能会失效。

二者的关系:

隐式原型指向创建这个对象的函数(constructor)的prototype

Q2:在IE中可以使用_proto_属性吗?

A:_proto_将在ES6中进行标准化,目前在ES6的草案附录B中。

Q3:_proto_的兼容性怎么样?

A:_proto_目前是浏览器的内置属性,不同的浏览器有不同的情况。

Q3:new function 和 new object 的差别?

A3:JS之中没有new fuction,我的理解是通过构造函数实例化一个对象?

new Object()就是通过Objec()t这个函数产生的,它会继承Object的所有东西;

同样的,通过构造函数new出来(实例化)的,会继承构造函数里面的属性和方法。js的new关键字传承的机制,这点倒是和其他语言差不多。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值