谈谈JavaScript的原型、原型链、构造函数、prototype、__proto__和constructor

  原型、原型链、构造函数是JavaScript比较难的知识点,但是它们又功能强大,是我们进行组件开发、模块开发必须掌握的技能,翻阅网上相关的博文,个人觉得这几篇博文不错,可以一读:
  1)汤姆大叔:强大的原型和原型链
  2)深入理解JavaScript系列(10):JavaScript核心(晋级高手必读篇)
  3)三张图搞懂JavaScript的原型对象与原型链
  4)Js中Prototype、__ proto __、Constructor、Object、Function关系介绍
  5)前端基础进阶(九):详解面向对象、构造函数、原型与原型链
  因此,本文不再大篇幅图文介绍JavaScript对象、原型、原型链、构造函数等知识点,而是力求用简单文字、代码输出剖析prototype、__proto__和constructor三者间的关系。

1、prototype和__proto__

  • 1)prototype是函数(function)才有的属性;
  • 2)__proto__是每个对象(object)都有的属性,指向对象构造函数的prototype;
var a = {};				// 等同 a = new Object();
console.log(a.prototype);  //普通对象没有prototype属性,->undefined
console.log(a.__proto__);  //构造函数原型, Object.prototype, ->Object{...}

var b = function(){}
console.log(b.prototype);  //b {}
console.log(b.__proto__);  // = Function.prototype, ->function() {}

说明:Function.prototype = function,是特例,下文会继续讲解。

  • 3)__proto__构成原型链,Object.prototype.__proto __= null,原型链结束
var a = {};
console.log(a.__proto__);  //=Object.prototype, ->Object {}
console.log(a.__proto__.__proto__);  //=Object.prototype.__proto__, ->null

原型链从继承角度理解就是找父类,以Java为例:
1)a是一个普通对象实例,则a的父类是基类Object;
2)基类Object没有父类,因此可以理解其父类为null。
而JavaScript用原型链表示这种继承关系,用对象的__proto__属性构成原型链:
1)a.__ proto __ = Object.prototype
2)a.__ proto __ . __ proto __ = Object.prototype. __ proto __ = null

  • 4)__ proto __,通常指向对象构造函数的prototype,有一种情况例外Object.create方式创建的对象。
var a1 = {};
var a2 = Object.create(a1);
console.log(a2.__proto__==a1)	->true

用Object.create(a1)创建的对象,其__proto__会指向a1,因此对于a2来说,其原型链为:
a2.__ proto __ = a1;
a1.__ proto __ = Object.prototype;
a2.__ proto __ . __ proto __ . __ proto __ = null

2、Prototype和Constructor

在 JavaScript 中,每个函数对象都有prototype属性,用于引用原型对象。prototype对象又有隐藏属性constructor,它反过来引用函数本身,是一种循环引用。

function Animal(){
}
var anim = new Animal();
console.log(anim.constructor===Animal);	//anim由Animal构造出来,->true
console.log(Animal===Animal.prototype.constructor); //prototype对象的隐藏属性constructor反过来引用函数本身,->true
/**
 * Animal = new Function()
 * 因此Animal.constructor = Function,
 * 而 Function = Function.prototype.constructor
 * Animal.constructor = Function.prototype.constructor
 */
console.log(Animal.constructor===Function.prototype.constructor); // ->true
console.log(Function.prototype.constructor===Function);    //true

3、深入理解Function、Object

JavaScript中有几个迷惑的地方
1)Function、Object是函数;
2)new Function仍然是函数,new Object却是对象;
3)new (new Function) 又是对象;

var o2 =new Object();
var f3 = new Function('str','console.log(str)');
console.log('typeof Object:'+typeof Object);        //function
console.log('typeof Function:'+typeof Function);    //function
console.log('typeof o2:'+typeof o2);   				//object
console.log('typeof f3:'+typeof f3);   				//function
console.log('typeof new f3:'+typeof new f3());   	//object

Function.prototype = function,是一个特例

console.log(typeof Function.prototype);  //这是一个特例, ->function
console.log(typeof Function.__proto__);  //function
console.log(typeof Function.__proto__ == Function.prototype) ->true
console.log(typeof Function.prototype.prototype); //undefined, 正常来说Function.prototype = function, function.prototype = object
console.log(typeof Function.prototype.__proto__); //object,这个要记住,后面会详细解释

console.log(typeof Object.prototype);	//object, 好理解,Object是一个function
console.log(typeof Object.__proto__); //function, 好理解, Object = new Function,Object.__proto__ = Function.prototype
console.log(Object.prototype.prototype); //undefied, 好理解, Object.prototype = object(只有function才有prototype,所以prototype=undefiend)
console.log(Object.prototype.__proto__===null);  //null, 必须记住,原型链结束

console.log(Function.prototype===Object.__proto__);   //true,上面代码已经解释
console.log(Function.__proto__===Object.__proto__);   //true, 因为Function.prototype = Function.__proto__
console.log(Function.prototype.__proto__===Object.prototype);   //true,有点不明白?

Function.prototype. __ proto __=Object.prototype解释

console.log(Function instanceof  Object); // true
console.log(Object instanceof Function);  // true

根据instanceof原理,我们可以得出结论:

  • Object.prototype(object)在Function的原型链上有;
    Function . __ proto __ = function, != Object.prototype
    因此只有Function . __ proto__ . __ proto __ = Object.prototype,
    由于Function . __ proto__ = Function.prototype, 因此:
    Function.prototype. __ proto __=Object.prototype
  • Function.prototype在Object的原型链上有;

猜你喜欢

转载自blog.csdn.net/chuangxin/article/details/84918893
今日推荐