JS原型、原型链理解(一)

JS原型、原型链理解(一)

原型:是JavaScript中一个比较难理解的概念,原型对象是包含特定类型的所有实例共享的属性和方法。原型相关的属性也比较多,对象有prototype属性,函数对象有prototype属性,原型对象有constructor属性。原型对象的好处是,可以让所有实例对象共享它所包含的属性和方法。(原型对象就是构造函数的一个实例对象。)


一、初识原型

在JavaScript中,原型也是一个对象,通过原型可以实现对象的属性继承,JavaScript的对象中都包含了一个Prototype内部属性,这个属性所对应的就是该对象的原型。
Prototype作为对象的内部属性,是不能被直接访问的。所以为了方便查看一个对象的原型,大多数浏览器提供了__proto__这个非标准(不是所有浏览器都支持)的访问器(ECMA引入了标准对象原型访问器Object.getPrototype(object))。在JavaScript的原型对象中,还包含一个”constructor”属性,这个属性对应创建所有指向该原型的实例的构造函数

注意:
1. 在函数里有一个属性prototype,由该函数创建的对象默认会连接到该属性上。
2.__proto__是站在对象角度来说的,而prototype是站在构造函数角度来说的。

二、规则

在JavaScript中,每个函数都有一个prototype属性,当一个函数被用作构造函数来创建实例时,这个函数的prototype属性值会被作为原型赋值给所有对象实例(也就是设置实例的__proto__属性),也就是说,所有实例的原型引用的是函数的prototype属性。换言之JavaScript中任意对象都有一个内置属性prototype,在ES5之前没有标准的方法访问这个内置属性,但是大多数浏览器都支持通过__proto__来访问

'use strict';//以严格模式运行javascript代码
function Person(name, age)
{
  this.name = name;
  this.age = age;
}
var p = new Person('张三', 20);
Person.prototype.salary = null;
p.salary = 2000;
console.log(p.name);//控制台输出张三
console.log(p.salary);//控制台输出2000
//下面是伪代码
var p = new Person(); 
//于是有
p.__proto__ === Person.prototype //true
//又因为
Person.prototype === ('张三', 20, 2000);//true
//所以
p.__proto__ === ('张三', 20, 2000);
三、初识Object

Object对象本身是一个函数对象。既然是Object函数,就肯定会有prototype属性,所以可以看到Object.prototype的值就是Object {}这个原型对象。反过来,当访问Object.prototype对象的constructor这个属性的时候,就得到了Obejct函数。
另外,当通过Object.prototype._proto_获取Object原型的原型的时候,将会得到null,也就是说Object {}原型对象就是原型链的终点了。

var obj = new Object();
//对象是有原型对象的
//原型对象也有原型对象 
obj._proto_._proto_._proto_
//原型对象也有原型对象,对象的原型对象一直往上找,会找到一个null
// 原型链示例
var arr = [];
arr -> Array.prototype ->Object.prototype -> null
var o = new Object();
o -> Object.prototype -> null;
四、初识Function

如上面例子中的构造函数,JavaScript中函数也是对象,所以就可以通过__proto__查找到构造函数对象的原型。
function对象作为一个函数,就会有prototype属性,该属性将对应function(){}对象。
function对象作为一个对象,就有__proto__属性,该属性对应function.prototype,也就是说,function._proto_ === function.prototype

在这里对prototype(显式原型)和proto(隐式原型)进行简单的介绍:
显式原型:
每一个函数在创建之后都会拥有一个名为prototype的属性,这个属性指向函数的原型对象。(Function.prototype.bind方法构造出来的函数是个例外,它没有prototype属性)
隐式原型:
对于所有的对象,都有__proto__属性,这个属性对应该对象的原型。
对于函数对象,除了__proto__属性之外,还有prototype属性,当一个函数被用作构造函数来创建实例时,该函数的prototype属性值将被作为原型赋值给所有对象实例(也就是设置实例的__proto__属性)

  • 二者关系:隐式原型指向创建这个对象的函数(constructor)的prototype
  • 作用:
    显式原型的作用:用来实现基于原型的继承与属性的共享。
    隐式原型的作用:构成原型链,同样用于实现基于原型的继承。举个例子,当我们访问obj这个对象中的x属性时,如果在obj中找不到,那么就会沿着__proto__依次查找。
五、总结

原型


  1. 构造函数Foo()构造函数的原型属性Foo.prototype指向了原型对象,在原型对象里有共有的方法,所有构造函数声明的实例(这里是f1,f2)都可以共享这个方法。
  2. 原型对象Foo.prototype``Foo.prototype保存着实例共享的方法,有一个指针constructor指回构造函数。
  3. 实例f1和f2是Foo这个对象的两个实例,这两个对象也有属性__proto__,指向构造函数的原型对象,这样子就可以像上面1所说的访问原型对象的所有方法啦。另外:构造函数Foo()除了是方法,也是对象啊,它也有__proto__属性,指向谁呢?指向它的构造函数的原型对象呗。函数的构造函数不就是Function嘛,因此这里的__proto__指向了Function.prototype。其实除了Foo()Function()Object()也是一样的道理。原型对象也是对象啊,它的__proto__属性,又指向谁呢?同理,指向它的构造函数的原型对象呗。这里是Object.prototype。最后,Object.prototype__proto__属性指向null

小结:
1.对象有属性__proto__,指向该对象的构造函数的原型对象。
2.方法除了有属性__proto__,还有属性prototypeprototype指向该方法的原型对象。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值