笔记-JS 原型与原型链知解

来源:互联网 发布:淘宝二次元粉丝节 编辑:程序博客网 时间:2024/05/18 00:34

原型及原型链是JavaScript中的重难点。本文是作者对JS原型与原型链相关内容的学习笔记,希望对各位读者大人会有所帮助。若有疑问或不正之处,欢迎提出指正和讨论。


1、对象

众所周知,在JavaScript中,万物皆对象。不过,对象分两类:普通对象和函数对象。Object和Function是JS自带的函数对象。

var a1 = {}

var a2 = new Object();

var f1 = function(){};

var f2 = new Function('sayhi', 'alert("hello world!")')

console.log(typeof Object);   //function

console.log(typeof Function);   //function

console.log(typeof a);   //object

console.log(typeof f);    //function

从以上示例,可以看出,凡是通过new Function()创建的对象都是函数对象,其他都是普通对象


2、构造函数

function Person(name){

this.name = name;

this.sayName = function(){ alert(this.name) }

}

var per1 = new Person("lin");

var per2 = new Person("fang");

console.log( per1.constructor == Person );   //true

console.log( per2.constructor == Person );   //true

从以上示例,可以看到per1和per2都是Person(构造函数)的实例,实例存在一个constructor属性,该属性指向Person,即:实例的constructor属性指向其构造函数


3、原型对象

在JavaScript中,定义一个对象时,对象都会包含一些默认属性。每个对象都有__proto__属性,只有函数对象才存在prototype属性,该属性指向函数的原型对象

原型对象,顾名思义,就是普通对象。

Person.prototype = {   name:  'lin',   sayName: function() {     alert(this.name);   }}
在以上示例中,可以看到,我们给Person.prototype添加了两个属性:name、sayName,其实还存在一个默认属性:constructor。

在默认情况下,所有的原型对象都存在一个默认属性constructor,该属性指向prototype属性所在的函数;即:Person.prototype.constructor == Person

在此我们得出一个结构:原型对象( Person.prototype )是构造函数( Person )的一个实例对象


实例对象、原型对象、构造函数的关系如下:



4、_proto_

很多浏览器都给每个对象提供了__proto__内置属性,该属性就是该对象的[[ prototype ]],用于指向创建它的构造函数的原型对象

即per1.__proto_ _== Person.prototype;

由此我们得到如下关系:::

Person.prototype.constructor == Person;per1.__proto__ == Person.prototype;per1.constructor == Person;

在此我们要明确一点:::此关系存在于实例(per1)与构造函数(Person)的原型对象(Person.prototype)之间,而不是存在于实例(per1)与构造函数(Person)之间。

per1.constructor.prototype = Person.__proto__


5、构造器

众所周知,在JavaScript中,新对象是通过new操作符后跟一个构造函数来创建的。

如:var obj = {};等同于var obj = new Object();


6、函数对象

所有函数对象的__proto__属性都指向了Function.prototype,它是一个空函数(empty function)。

JavaScript中有12个内置构造器/对象(Number、Array、Boolean、String、Date、Object、Function、RegExp、Error及Global、Arguments、Math、JSON),其中Global无法直接访问,Arguments只在函数调用时由JS引擎创建,Math和JSON以对象形式存在,无需new。它们的__proto__就是Object.prototype。

Array.__proto__ === Function.prototype // true
Array.constructor == Function //true
Math.__proto__ === Object.prototype // true
Math.constructor == Object//true
Object.__proto__ === Function.prototype // true
Object.constructor == Function // true
Function.__proto__ === Function.prototype // true
Function.constructor == Function //true

由此可见,所有的构造器都来自Function.prototypre,甚至包括Object和Function自身;所有的构造器都继承了Function.prototype的属性和方法。如:call、apply等

Function.prototype.__proto__ === Object.prototype//trueObject.prototype.__proto__ === null//true
这真的是”无中生有“啊。

Function.prototype是唯一一个type xxx.prototype为function的prototype,其他构造器都是一个对象。

console.log(typeof Function.prototype) // function
console.log(typeof Object.prototype) // object
console.log(typeof Array.prototype) // object


7、总结

(1)实例的constructor属性指向其构造函数;

(2)每个对象都有__proto__属性,该属性指向函数的原型对象(而不是构造函数);

        a、普通对象的__proto__指向了这个对象(this)的构造函数的prototype

        b、函数对象的__proto__全部指向了Function的prototype

(3)原型链的形成靠的是__proto__而不是prototype;



本文为JS原型链学习笔记。

如有不妥之处,敬请斧正。





原创粉丝点击