js原型和原型链怎么理解??_proto_ 和 _js prototype 原型什么区别??

最详尽的 JS 原型与原型链终极详解,没有「可能是」。(一) - 简书
最详尽的 JS 原型与原型链终极详解,没有「可能是」。(一)
三篇文章都更新完毕,完整的剖析了 JS 原型与原型链,希望通过这些教程能让你对 Javascript 这门语言理解的更透彻!
一. 普通对象与函数对象
JavaScript 中,万物皆对象!但对象也是有区别的。分为普通对象和函数对象,Object 、Function 是 JS 自带的函数对象。下面举例说明
var o1 = {};
var o2 =new Object();
var o3 = new f1();
function f1(){};
var f2 = function(){};
var f3 = new Function('str','console.log(str)');
console.log(typeof Object); //function
console.log(typeof Function); //function
console.log(typeof f1); //function
console.log(typeof f2); //function
console.log(typeof f3); //function
console.log(typeof o1); //object
console.log(typeof o2); //object
console.log(typeof o3); //object
在上面的例子中 o1 o2 o3 为普通对象,f1 f2 f3 为函数对象。怎么区分,其实很简单,凡是通过 new Function() 创建的对象都是函数对象,其他的都是普通对象。f1,f2,归根结底都是通过 new Function()的方式进行创建的。Function Object 也都是通过 New Function()创建的。
一定要分清楚普通对象和函数对象,下面我们会常常用到它。
二. 构造函数
我们先复习一下构造函数的知识:
function Person(name, age, job) {
this.name =
this.age =
this.job =
this.sayName = function() { alert(this.name) }
var person1 = new Person('Zaxlct', 28, 'Software Engineer');
var person2 = new Person('Mick', 23, 'Doctor');
上面的例子中 person1 和 person2 都是 Person 的实例。这两个实例都有一个 constructor (构造函数)属性,该属性(是一个指针)指向 Person。 即:
console.log(person1.constructor == Person); //true
console.log(person2.constructor == Person); //true
我们要记住两个概念(构造函数,实例):person1 和 person2 都是 构造函数 Person 的实例 一个公式: 实例的构造函数属性(constructor)指向构造函数。
三. 原型对象
在 JavaScript 中,每当定义一个对象(函数也是对象)时候,对象中都会包含一些预定义的属性。其中每个函数对象都有一个prototype 属性,这个属性指向函数的原型对象。(先用不管什么是 __proto__ 第二节的课程会详细的剖析)
function Person() {}
Person.prototype.name = 'Zaxlct';
Person.prototype.age
Person.protetype.job
= 'Software Engineer';
Person.prototype.sayName = function() {
alert(this.name);
var person1 = new Person();
person1.sayName(); // 'Zaxlct'
var person2 = new Person();
person2.sayName(); // 'Zaxlct'
console.log(person1.sayname == person2.sayname); //true
我们得到了本文第一个「定律」:
每个对象都有 __proto__ 属性,但只有函数对象才有 prototype 属性
那什么是原型对象呢?我们把上面的例子改一改你就会明白了:
Person.prototype = {
job: 'Software Engineer',
sayName: function() {
alert(this.name);
原型对象,顾名思义,它就是一个普通对象(废话 = =!)。从现在开始你要牢牢记住原型对象就是 Person.prototype ,如果你还是害怕它,那就把它想想成一个字母 A: var A = Person.prototype
在上面我们给 A 添加了 四个属性:name、age、job、sayName。其实它还有一个默认的属性:constructor
在默认情况下,所有的原型对象都会自动获得一个 constructor(构造函数)属性,这个属性(是一个指针)指向 prototype 属性所在的函数(Person)
上面这句话有点拗口,我们「翻译」一下:A 有一个默认的 constructor 属性,这个属性是一个指针,指向 Person。即:Person.prototype.constructor == Person
在上面第二小节《构造函数》里,我们知道实例的构造函数属性(constructor)指向构造函数
:person1.constructor == Person
这两个「公式」好像有点联系:
person1.constructor == Person
Person.prototype.constructor == Person
person1 为什么有 constructor 属性?那是因为 person1 是 Person 的实例。那 Person.prototype 为什么有 constructor 属性??同理, Person.prototype (你把它想象成 A) 也是Person 的实例。也就是在 Person 创建的时候,创建了一个它的实例对象并赋值给它的 prototype,基本过程如下:
var A = new Person();
Person.prototype = A;
结论:原型对象(Person.prototype)是 构造函数(Person)的一个实例。
原型对象其实就是普通对象(但 Function.prototype 除外,它是函数对象,但它很特殊,他没有prototype属性(前面说道函数对象都有prototype属性))。看下面的例子:
function Person(){};
console.log(Person.prototype) //Person{}
console.log(typeof Person.prototype) //Object
console.log(typeof Function.prototype) // Function,这个特殊
console.log(typeof Object.prototype) // Object
console.log(typeof Function.prototype.prototype) //undefined
Function.prototype 为什么是函数对象呢?
var A = new Function ();
Function.prototype = A;
上文提到凡是通过 new Function( ) 产生的对象都是函数对象。因为 A 是函数对象,所以Function.prototype 是函数对象。
那原型对象是用来做什么的呢?主要作用是用于继承。举个例子:
var Person = function(name){
this.name = // tip: 当函数执行时这个 this 指的是谁?
Person.prototype.getName = function(){
return this.
// tip: 当函数执行时这个 this 指的是谁?
var person1 = new person('Mick');
person1.getName(); //Mick
从这个例子可以看出,通过给 Person.prototype 设置了一个函数对象的属性,那有 Person 的实例(person1)出来的普通对象就继承了这个属性。具体是怎么实现的继承,就要讲到下面的原型链了。
小问题,上面两个 this 都指向谁?
var person1 = new person('Mick');
person1.name = 'Mick'; // 此时 person1 已经有 name 这个属性了
person1.getName(); //Mick
故两次 this
在函数执行时都指向 person1。
别着急走,关于原型与原型链还有第二篇第三篇呢~
本文部分参照了
(感谢原作者)(侵立删)和《JavaScript 高级程序设计》第三版
希望通过这一系列课程,能帮助你彻底搞明白 JavaScript 的原型与原型链 :)
能放到前端的都放到前端拒绝访问 |
| 百度云加速
请打开cookies.
此网站 () 的管理员禁止了您的访问。原因是您的访问包含了非浏览器特征(543cb-ua98).
重新安装浏览器,或使用别的浏览器一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!
二、互相尊重,对自己的言论和行为负责。
本文标题:
本页链接:拒绝访问 | www. | 百度云加速
请打开cookies.
此网站 (www.) 的管理员禁止了您的访问。原因是您的访问包含了非浏览器特征(c43d1-ua98).
重新安装浏览器,或使用别的浏览器& & & & var&o1&=&{};&&&&&&&&var&o2&=new&Object();&&&&&&&&&&&&&&&&function&f1(){}&&&&&&&&var&f2&=&function(){}&&&&&&&&var&f3&=&new&Function('str','console.log(str)');&&&&&&&&&&&&f3('aabb');&&&//&aabb&&&&&&&&console.log('typeof&Object:'+typeof&Object);&&&&&&&&&&&&//function&&&&&&&&console.log('typeof&Function:'+typeof&Function);&&&&&&&&//function&&&&&&&&console.log('typeof&o1:'+typeof&o1);&&&//object&&&&&&&&console.log('typeof&o2:'+typeof&o2);&&&//object&&&&&&&&console.log('typeof&f1:'+typeof&f1);&&&//function&&&&&&&&console.log('typeof&f2:'+typeof&f2);&&&//function&&&&&&&&console.log('typeof&f3:'+typeof&f3);&&&//function通常我们认为o1、o2是对象,即普通对象;f1、f2、f3为函数。但是其实函数也是对象,是由Function构造的,f3这种写法就跟对象的创建的写法一样。f1、f2最终也都像f3一样是有Function这个函数构造出来的f1、f2、f3为函数对象,Function跟Object本身也是函数对象。& &&& &Js中每个对象(null除外)都和另一个对象相关联,通过以下例子跟内存效果图来分析Function、Object、Prototype、__proto__对象间的关系。&&&&function&Animal(){&&&&&&&&&&&&}&&&&var&&anim&=&new&Animal();&&&&&&&&console.log('***********Animal&anim&proto*****************');&&&&console.log('typeof&Animal.prototype:'&+typeof&Animal.prototype);&&//object&&&&&console.log('anim.__proto__===Animal.prototype:'+(anim.__proto__===Animal.prototype));&&//true&&&&console.log('Animal.__proto__===Function.prototype:'+(Animal.__proto__===Function.prototype));&&//true&&&&console.log('Animal.prototype.__proto__===Object.prototype:'+(Animal.prototype.__proto__===Object.prototype));&&//true&&&&&&&&console.log('***********Function&proto*****************');&&&&console.log('typeof&Function.prototype:'+typeof&Function.prototype);&&//function&&&&console.log('typeof&Function.__proto__:'+typeof&Function.__proto__);&&//function&&&&console.log('typeof&Function.prototype.prototype:'+typeof&Function.prototype.prototype);&//undefined&&&&console.log('typeof&Function.prototype.__proto__:'+typeof&Function.prototype.__proto__);&&&//object&&&&console.log('Function.prototype===Function.__proto__:'+(Function.prototype===Function.__proto__));&//true&&&&console.log('***********Object&proto*****************');&&&&console.log('typeof&Object.prototype:'+typeof&Object.prototype);&&//object&&&&console.log('typeof&Object.__proto__:'+typeof&Object.__proto__);&&//function&&&&console.log('Object.prototype.prototype:'+Object.prototype.prototype);&&//undefied&&&&console.log('Object.prototype.__proto__===null:'+(Object.prototype.__proto__===null));&&//null&&&&console.log('***********Function&Object&&proto关系*****************');&&&&console.log('Function.prototype===Object.__proto__:'+(Function.prototype===Object.__proto__));&&&//true&&&&console.log('Function.__proto__===Object.__proto__:'+(Function.__proto__===Object.__proto__));&&&//true&&&&console.log('Function.prototype.__proto__===Object.prototype:'+(Function.prototype.__proto__===Object.prototype));&&&//true&&&&/*********************&系统定义的对象Array、Date&****************************/&&&&console.log('**************test&Array、Date****************');&&&&&&&&&&var&array&=&new&Array();&&&&var&date&=&new&Date();&&&&console.log('array.__proto__===Array.prototype:'+(array.__proto__===Array.prototype));&&&//true&&&&console.log('Array.__proto__===Function.prototype:'+(Array.__proto__===Function.prototype));&&//true&&&&console.log('date.__proto__===Date.prototype:'+(date.__proto__===Date.prototype));&&&&//true&&&&console.log('Date.__proto__===Function.prototype:'+(Date.__proto__===Function.prototype));&&&&&//trueFunction、Object、Prototype、__proto__内存关系图& &&&&&&上面的内存图跟堆栈结构可以参照文章。& &&&&&&堆区图说明:&& & && &Function.prototype函数对象图内部表示prototype属性的红色虚框,只是为了说明这个属性不存在。& &&& &&通过上图Function、Object、Prototype关系图中,可以得出一下几点:所有对象所有对象,包括函数对象的原型链最终都指向了Object.prototype,而Object.prototype.__proto__===null,原型链至此结束。Animal.prototype是一个普通对象。Object是一个函数对象,也是Function构造的,Object.prototype是一个普通对象。Object.prototype.__type__指向null。Function.prototype是一个函数对象,前面说函数对象都有一个显示的prototype属性,但是Function.prototype却没有prototype属性,即Function.prototype.prototype===undefined,所有Function.prototype函数对象是一个特例,没有prototype属性。Object虽是Function构造的一个函数对象,但是Object.prototype没有指向Function.prototype,即Object.prototype!==Function.prototype。二 & &Prototype跟Constructor关系介绍& & &&&&&在 JavaScript 中,每个函数对象都有名为“prototype”的属性(上面提到过Function.prototype函数对象是个例外,没有prototype属性),用于引用原型对象。此原型对象又有名为“constructor”的属性,它反过来引用函数本身。这是一种循环引用(i.e.&Animal.prototype.constructor===Animal)。& &&& &&通过以下例子跟内存效果图来分析Prototype、constructor间的关系。& & console.log('**************constructor****************');&&&&&console.log('anim.constructor===Animal:'+(anim.constructor===Animal))&&&&;&&&&//true&&&&console.log('Animal===Animal.prototype.constructor:'+(Animal===Animal.prototype.constructor))&&&&;&&&&//true&&&&console.log('Animal.constructor===Function.prototype.constructor:'+(Animal.constructor===Function.prototype.constructor));&&&//true&&&&console.log('Function.prototype.constructor===Function:'+(Function.prototype.constructor===Function));&&&&//true&&&&console.log('Function.constructor===Function.prototype.constructor:'+(Function.constructor===Function.prototype.constructor));&&&&//true&&&&console.log('Object.prototype.constructor===Object:'+(Object.prototype.constructor===Object));&&&&//true&&&&console.log('Object.constructor====Function:'+(Object.constructor===Function));&&&&//true&prototype、constructor内存关系图(在Function、Object、Prototype关系图上加入constructor元素):& & & & 上图中,红色箭头表示函数对象的原型的constructor所指向的对象。注意Object.constructor===Function;本身Object就是Function函数构造出来的 & & & &如何查找一个对象的constructor,就是在该对象的原型链上寻找碰到的第一个constructor属性所指向的对象。参考:&(javascript原理介绍)&(JavaScript 的原型对象 Prototype)&(理解js中的原型链,prototype与__proto__的关系)
&re: Js中Prototype、__proto__、Constructor、Object、Function关系介绍[未登录]&&&&
啥都不说了 解惑了 十分感谢
&re: Js中Prototype、__proto__、Constructor、Object、Function关系介绍[未登录]&&&&
不过我测试的是Object.constructor返回:function Function() { [native code] }Object.prototype.constructor返回:function Object() { [native code] }也不是同一个啊 图中画的指向是同一个 这是怎么回事儿?望解惑
&re: Js中Prototype、__proto__、Constructor、Object、Function关系介绍[未登录]&&&&
Object.constructor返回:function Function() { [native code] }Object.prototype.constructor返回:function Object() { [native code] }都回指向内部__proto__
&re: Js中Prototype、__proto__、Constructor、Object、Function关系介绍&&&&
@ddObject.constructor,其实是取取值于Function.prototype中的Constructor,即为Function.而Object.prototype.Constructor却是指向构造该对象的函数即,Object函数.
&re: Js中Prototype、__proto__、Constructor、Object、Function关系介绍&&&&
(i.e. Animal.prototype.constructor===Animal)这句的前提是 Animal没有原型对象, 否则应该全等于原型对象所处的类型本身。
&re: Js中Prototype、__proto__、Constructor、Object、Function关系介绍[未登录]&&&&
Function.prototype没有prototype属性,作为函数对象有什么用?为什么不直接令他为普通对象
&re: Js中Prototype、__proto__、Constructor、Object、Function关系介绍&&&&
为啥object其实是一个函数对象。js里万物皆对象。。但object的原型属性为啥要指向function.prototype.不是object本身也有个prototype对象吗
&re: Js中Prototype、__proto__、Constructor、Object、Function关系介绍&&&&
&re: Js中Prototype、__proto__、Constructor、Object、Function关系介绍&&&&
@dd两个还是有区别的
&re: Js中Prototype、__proto__、Constructor、Object、Function关系介绍[未登录]&&&&
new Animal指向好像错了,貌似是直接指向Animal.prototype
&re: Js中Prototype、__proto__、Constructor、Object、Function关系介绍&&&&
@lei确实
&re: Js中Prototype、__proto__、Constructor、Object、Function关系介绍&&&&
博主写的这篇文章真牛逼,解惑!
阅读排行榜
评论排行榜}

我要回帖

更多关于 prototype proto 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信