`
897371388
  • 浏览: 529460 次
文章分类
社区版块
存档分类
最新评论

深入理解__proto__ 、constructor和prototype的关系

 
阅读更多
<!doctype html>
<html>
<head>
	<meta charset="utf-8">
</head>
<body>
<script type="text/javascript">
/**

@authors Benjamin
@date    2013-11-12 10:23:40
深入理解javascript 原型和原型链

最近不是很忙,空余时间整理最近几天看到的关于原型和原型链的文章,收获还是不小的。
今天十八届三中全会即将闭幕,期待新一届领导班子的改革方略,能够惠民吧
房价,户籍都是让80后很蛋疼的问题哈,当然,做为屌丝的我,肯定也是。
开篇先了解下两个很有用的属性:

一、__proto__属性:

__proto__属性未来会成为ES6标准的一部分,目前,该属性在各个浏览器下的实现差别也许比较大.Firefox是最先实现的这个魔法属性(magic property)的浏览器,而且该属性在Firefox中的表现也最有望能成为标准.我们通常用的__proto__属性都是从Object.prototype上继承下来的,那到底__proto__与prototype什么关系呢?

1)所有构造器/函数的__proto__都指向Function.prototype,它是一个空函数(Empty function)
看看实例:

*/ 
console.log(Number.__proto__   === Function.prototype) // true
console.log(Boolean.__proto__  === Function.prototype) // true
console.log(String.__proto__   === Function.prototype) // true
console.log(Object.__proto__   === Function.prototype) // true
console.log(Function.__proto__ === Function.prototype) // true 
console.log(Array.__proto__    === Function.prototype) // true
console.log(RegExp.__proto__   === Function.prototype) // true
console.log(Error.__proto__    === Function.prototype) // true
console.log(Date.__proto__     === Function.prototype) // true

/*
JavaScript中有内置(build-in)构造器/对象共计12个(ES5中新加了JSON),这里列举了可访问的8个构造器。剩下如Global不能直接访问,Arguments仅在函数调用时由JS引擎创建,Math,JSON是以对象形式存在的,无需new。它们的__proto__是Object.prototype。如下
*/

console.log("对象测试...");
console.log(Math.__proto__ === Object.prototype);//true
console.log(JSON.__proto__ === Object.prototype);//true

/**
 * 上面说的“所有构造器/函数”当然包括自定义的。看下面的例子:
 */

var Employee = function (){

};

function Person(){

}
console.log("自定义函数测试...");
console.log(Employee.__proto__  === Function.prototype);//true
console.log(Person.__proto__ === Function.prototype);//true

/**
 * 由以上测试得出,所有的构造器都来自于Function.prototype,甚至包括根构造器Object及Function自身。所有构造器都继承了Function.prototype的属性及方法。如length、call、apply、bind(ES5)。另,Function.prototype也是唯一一个typeof XXX.prototype为 “function”的prototype。其它的构造器的prototype都是一个对象,下面来测试下:
*/

console.log("类型测试中...");
console.log(typeof Function.prototype) // function
console.log(typeof Object.prototype)   // object
console.log(typeof Number.prototype)   // object
console.log(typeof Boolean.prototype)  // object
console.log(typeof String.prototype)   // object
console.log(typeof Array.prototype)    // object
console.log(typeof RegExp.prototype)   // object
console.log(typeof Error.prototype)    // object
console.log(typeof Date.prototype)     // object
console.log(typeof Object.prototype)   // object

/**
 * Function.prototype 是一个空函数,我们来测试下
 */

console.log("空函数测试...");
console.log(Function.prototype);//function(){}

//用alert来看会更直接点
//alert(Function.prototype);//function(){}

/**
 * 下面我们来看看Function.prototype 的__proto__是谁呢?看下面的测试
 */

console.log("Function.prototype的__proto__测试...");
console.log(Function.prototype.__proto__ === Object.prototype);//true

/**
 * 那Object.prototype的__proto__又是谁呢?看下面测试
 */

console.log(Object.prototype.__proto__);//输出null

/*
2)所有对象的__proto__都指向其构造器的prototype
来看看以下实例
*/

console.log("对象的__proto__测试中...");

//函数声明
function Foo(){

}
var foo = new Foo();//对象实例化

console.log(foo.__proto__ === Foo.prototype);//true

//函数表达式
var Foo = function (){}
var foo = new Foo();//对象实例化
console.log(foo.__proto__ === Foo.prototype);//true

/**
 * 看完自定义函数,下面我们来看看javascript引擎内置构造器
 */

var 
arr = ["aaa", "bbb"],
reg = /^abc$/g,
obj = {
	name: "张三",
	age: 20
},
date = new Date(),
error = new Error("fdasfdasfd");

console.log("内置构造器的对象测试...");
console.log(arr.__proto__ === Array.prototype);//true
console.log(obj.__proto__ === Object.prototype);//true
console.log(reg.__proto__ === RegExp.prototype);//true
console.log(date.__proto__ === Date.prototype);//true
console.log(error.__proto__ === Error.prototype);//true

/**
 * 二、constuctor属性
 * constructor属性始终指向创建当前对象的构造函数,看下面的实例
 */
var 
arr = ["aaa", "bbb"],
reg = /^abc$/g,
obj = {
	name: "张三",
	age: 20
},
date = new Date(),
error = new Error("fdasfdasfd");

console.log("constructor指向测试...");
console.log(arr.constructor === Array);//true
console.log(obj.constructor === Object);//true
console.log(reg.constructor === RegExp);//true
console.log(date.constructor === Date);//true
console.log(error.constructor === Error);//true

/**
 * 我们都知道函数是对象,对象都有prototype属性,那么这个prototype的constructor属性指向谁呢?
 * 由以下实例得出结论,其constructor指也向其构造函数
 */
console.log("prototype的constructor属性指向测试...");
//函数声明
function Foo(){

}
console.log(Foo.prototype.constructor === Foo);//true
//函数表达式
var Foo = function (){

};
console.log(Foo.prototype.constructor === Foo);

/**
 * 那么一个函数的实例指向谁呢?
 */
function Foo(){

}
var f1 = new Foo();
console.log("测试constructor实例化指向...");
console.log(f1.constructor === Foo);
console.log(f1.constructor.prototype.constructor === Foo);

/**
 * 到此我们来必须来总结下子了:
 * f1 = new Foo();
 * f1.__proto__ === Foo.prototype.__proto__ === Object.prototype
 * Foo.prototype.constructor === Foo
 * Foo.__proto__ === Function.prototype.__proto__ === Object.prototype
 * 这样看起来貌似还是比较乱,下面用一张图来总结以上问题,如下图:
 */

/**
 * 开一个怪例子,当我们重定义prototype对象时,constructor的行为会有什么变化呢?
 */
function Foo(name){
	this.name = name;
}

Foo.prototype = {
	getName :function (){
		return this.name;
	}
};
var f1 = new Foo();
console.log("重定义prototype对象测试...");
console.log(f1.constructor === Foo); //false
console.log(Foo.prototype.constructor === Foo);//false
console.log(f1.constructor === Object);//true
console.log(Foo.prototype.constructor === Object);//true
/**
 * 是什么原因导致的此问题呢?来分析哈子,其实定义Foo.prototype = {}
 * 其实等价于Foo.prototype = new Object({"getName":function(){return this.name;}})
 * 因此Foo.prototype.constuctor === Obeject 返回true
 * 那么怎么让前面的两个false 变为true,做如下操作:
 */
Foo.prototype.constructor = Foo;
var f1 = new Foo();
console.log("重新指向测试...");
console.log(f1.constructor === Foo); //true
console.log(Foo.prototype.constructor === Foo);//true

</script>
</body>
</html>
分享到:
评论

相关推荐

    prototype,__proto,constructor

    分析javascript中 prototype __proto__ constructor之间的关系

    详解帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)

    主要介绍了详解帮你彻底搞懂JS中的prototype、__proto__与constructor(图解),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    JS中的原型以及prototype、constructor、__proto__三者之间的关系

    1、任何一个函数内都有prototype属性,这个prototype属性指向另一个对象 ,这个对象就是就是原型对象 ,简称原型。注意这个prototype是函数本身所自带的属性 2、原型的作用就是实现方法共享,将多个对象会调用的相同...

    TsangTszKin#HexoBlog#prototype、__proto__与constructor1

    它的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__属性所指向的那个对象(可以理解为父对象)里找,如果父对象也不存

    帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)

    作为一名前端工程师,必须搞懂JS中的prototype、__proto__与constructor属性,相信很多初学者对这些属性存在许多困惑,容易把它们混淆,本文旨在帮助大家理清它们之间的关系并彻底搞懂它们。这里说明一点,__proto__...

    图解prototype、proto和constructor的三角关系

    在javascript中,prototype、constructor以及__proto__之间有着“著名”的剪不断理还乱的三角关系,楼主就着自己对它们的浅显认识,来粗略地理理以备忘,有不对之处还望斧正。

    prototype与__proto__区别详细介绍

    prototype与__proto__区别 Each constructor is a function that has a property named “prototype” that is used to implement prototype-based inheritance and shared properties. Every object created by a ...

    傲娇大少之—【JS的原型,prototype、__proto__、constructor】

    不求甚解 – – liao一下prototype 如果你爱我,就干了这碗热热的毒鸡汤! 在父母的期望面前我们不敢说不行,我们总是用行动告诉他们我们是真的不行。欧耶! 关于prototype,怎么说呢,以前的前端开发是经常用的,...

    js构造函数constructor和原型prototype原理与用法实例分析

    __proto__, prototype和constructor 下面这三个属性的定义非常重要,始终贯穿在原型中。 prototype:此属性只有构造函数才有,它指向的是当前构造函数的原型对象。 __proto__:此属性是任何对象在创建时都会有的一...

    【JavaScript源代码】怎样用JavaScript实现原型模式.docx

     prototype警告:学习了解原型模式前需先学习原型、原型链、prototype、__proto__、constructor等知识; 实现原型模式 ES5中的API:Object.create(prototype, optionalDescriptorObjects) Object.create()方法...

    client-side-prototype-pollution:原型污染和有用的脚本小工具

    客户端原型污染 介绍 如果您不熟悉原型污染攻击,则应首先阅读以下内容: Olivier Arteau的NodeJS...constructor.prototype.test=test ?__proto__.test=test ?__proto__[test]=test ?__proto__[test]={"json":"value"}

    深入理解javascript prototype的相关知识

    如图比较好的阐述了prototype和__proto__ 简单的可以这么理解: 狗类A( function foo()),狗类A的模板描述:A.模板 (foo.prototype)是一个对象object, A.模板有个构造方法 foo.prototype.constructor=function foo()...

    Javascript中获取对象的原型对象的方法小结

    foo.__proto__ == F.prototype&#41;; 但是,__proto__属性在IE浏览器中一直到IE11才被支持。 那么在不支持__proto__属性的浏览器中,我们怎么得到对象的原型对象呢?可以通过constructor间接得到。 代码如下: &lt;

    JavaScript prototype属性深入介绍

    每个函数创建时默认带有一个prototype属性,其中包含一个constructor属性,和一个指向Object对象的隐藏属性__proto__。constructor属性的值为该函数的对象。在一个函数前面加上new来调用,则会创建一个隐藏连接到该...

    深入理解 ES6中的 Reflect用法

    console.log(Reflect.__proto__ === Object.prototype); // true console.log(obj.__proto__ === Reflect.__proto__); // true let str = '111'; console.log(str.__proto__); // String {"", length: 0, ...

    【JavaScript源代码】JavaScript中的几种继承方法示例.docx

    JavaScript中的几种继承方法示例  1.原型链继承  原理: 子类原型指向父类实例对象实现原型共享,即Son.prototype = new Father()。 这里先简单介绍下原型... obj.__proto__ === Object.prototype; //true console

    前端Javascript相关面试基础问答整理md

    10. prototype与__proto__的关系与区别 11. 继承的实现方式及比较 12. 深拷贝与浅拷贝 13. 防抖和节流 14. 作用域和作用域链、执行期上下文 15. DOM常见的操作方式 16. Array.sort()方法与实现机制 17. Ajax 17. ...

    JavaScript面向对象编程指南

    JavaScript面向对象编程指南不适合初学者 适合想提升JavaScript编程能力的人 prototype _proto_ constructor 浅拷贝深拷贝 JavaScript编程模式 设计模式

    JS原型、原型链深入理解

    原型是JavaScript中一个比较难理解的概念,原型相关的属性也比较多,对象有”prototype”属性,函数对象有”prototype”属性,原型对象有”constructor”属性。 一、初识原型 在JavaScript中,原型也是一个对象,...

Global site tag (gtag.js) - Google Analytics