理解javascript中的prototype

以前一直对javascript中的prototype不是很理解,今天在阅读了《javascript高级程序设计之后》终于理解了其中的prototype。来简单的总结一下从书中学习到的内容。

我们都知道在创建了一个function之后,这个function就具有了prototype这样的一个属性,利用这个prototype我们可以做很多的事情,其中我们经常用到的一点就是利用它来当做构造函数,因此,本文重要从function作为构造函数的角度来说明一下prototype。

其实javascript中的构造函数与其他的函数没有什么区别,只是调用的方式的略微点不一样。下面来看代码。

            function Dog(){
              this.name = "Ben";
           }

我们声明了一个简单的函数,叫做Dog,如果我们只是简单的调用这个方法 ,那么她只会为全局对象添加一个name属性。并不会生成对象。

但是当我们把这个方法当做构造函数来调用的时候,情况就会不一样了,这个函数会返回一个对象。

	var d = Dog();
	console.log(d) //undefined

        //作为构造函数调用
        var dog = new Dog();
        console.log(dog) // dog对象。

这属于javascript中生成对象的方式了,相信大家应该都明白,下面我们就来详细说明这个prototype在这个构造函数中到底起了什么作用。

在文章开头的时候,就已经说了,在声明构造函数的时候,这个函数已经prototype这样一个属性。在chrome的控制台中,输入代码可以查看到这样的一个结果。

<span style="font-size:18px;">          console.log(Dog.prototype); //Dog {} </span>

实际上函数的prototype指向了一个对象,称作为原型对象,这个对象其中包含了一个属性叫做constructor,但是为什么我们在输出的对象之中看不到它呢,这是在javascript中,把这个属性的Erumerable属性设置为false了,所以在这里我们看不到,但是看不到我们还是可以访问到这个属性。看下面的结果:

          console.log(Dog.prototype.constructor);
         // function Dog(){
         //     this.name = "Ben";
         //  } 

看到结果,是不是发现了什么,输出来的结构就是我们自己定义的构造函数,那么他们到底是什么关系呢?我们可以使用相等操作符来比较一下。

       console.log(Dog.prototype.constructor === Dog);//true

我们可以看到结果,这两个实际上是完成相等的。

这么说来,我们是不是又可以用constructor来访问到prototype呢?没错,这样是完全可以的,这样一样,这里面就相当于形成了一个循环指向关系,这个实际上也可以采用递归的方式来验证一下,调用递归的时候很快就会调用栈溢出,因为在这个递归调用中是没有出口的。

上面的关系我们可以简单的用下面的图来表示一下

好,上面我们已经简单的介绍了一下构造函数中的prototype,那么我们再来看一下,对象中的prototype,在javascript中,声明对象中并没有prototype这个属性,而是使用__proto__(注意:__是两个_) 来访问prototype ,那么对象中的__proto__跟构造函数中的prototype又是什么关系呢?

           dog.__proto__ === Dog.prototype;//true

结果一看便知,通过这个结果我们就可以知道同一个类的所有对象的__proto__都是相等的,因为他们实际上都指向了构造函数的prototype。

现在看完了,构造函数和对象的的prototype,我们再来看一下prototype这个对象本身,刚才我们已经提过了,prototype其实本身就是一个对象,既然他是一个对象,我们就可以扩展这个对象,下面我们为这个对象添加一个方法和属性。

Dog.prototype.say = function(){
console.log('wangwang');
}

Dog.prototype.color = "black";

我们再来看一下刚才自己定义的那个dog对象,是不是也有了这个方法和属性。

dog.day() ;// 'wangwang'
dog.color ;// 'black';

我们通过调用发现,这个这个对象上也有了个方法和属性,但是我们并没有直接在对象添加方法和属性,这就说明了,prototype中的属性和方法也会为对象共享。

在这里共享是通过查找得到的,当我们访问一个对象的属性时,这个对象首先会在自己的属性集里面去找这个属性,如果找到了,那么就直接返回,如果没有找到就会去prototype的属性集里面找。在这个例子中我们当我们访问属性和方法的时候,首先在dog对象里面找,找不到之后再去prototype的属性和方法找。

既然这些方法和属性都是共享的,那么我们修改这些方法和属性会有什么结果呢?

         var dog2 = new Dog();
         dog.color  = "red";
         console.log(dog2.color);  //black

从结果可以看到,dog2的color属性并没有受到影响,这是因为在使用对象去操作prototype的属性时,并没有真正的操作prototype,而是自己新建了一个color属性,并且将red赋值给了color,所以这里并没有影响到prototype。也就没有影响到dog2了。(读者可以自己验证一下,color是作为dog对象的属性而存在的)。

同样的我们可以看到当我们修改了方法之后,prototype中方法并没有收到影响。

关于prototype的简单说明就到这里。文中如有错位还望各位大神指正。

文章系原创,转载请注明

时间: 2024-10-13 00:27:53

理解javascript中的prototype的相关文章

深入理解Javascript中this, prototype, constructor

在Javascript面向对象编程中经常需要使用到this,prototype和constructor这3个关键字. 1.首先介绍一下this的使用:this表示当前对象;如果在全局中使用this,则this为当前页面对象window;如果在函数中使用this,则this为调用该函数的对象;可以使用apply和call两个全局函数来改变this的指向. 接下来,首先通过几个demo程序验证一下: function testFunction(){ console.log(this.variable

深入理解JavaScript中创建对象模式的演变(原型)

创建对象的模式多种多样,但是各种模式又有怎样的利弊呢?有没有一种最为完美的模式呢?下面我将就以下几个方面来分析创建对象的几种模式: Object构造函数和对象字面量方法 工厂模式 自定义构造函数模式 原型模式 组合使用自定义构造函数模式和原型模式 动态原型模式.寄生构造函数模式.稳妥构造函数模式 第一部分:Object构造函数和对象字面量方法 我之前在博文<javascript中对象字面量的理解>中讲到过这两种方法,如何大家不熟悉,可以点进去看一看回顾一下.它们的优点是用来创建单个的对象非常方

【干货理解】理解javascript中实现MVC的原理

理解javascript中的MVC MVC模式是软件工程中一种软件架构模式,一般把软件模式分为三部分,模型(Model)+视图(View)+控制器(Controller); 模型:模型用于封装与应用程序的业务逻辑相关的数据以及对数据处理的方法.模型有对数据直接访问的权利.模型不依赖 "视图" 和 "控制器", 也就是说 模型它不关心页面如何显示及如何被操作. 视图:视图层最主要的是监听模型层上的数据改变,并且实时的更新html页面.当然也包括一些事件的注册或者aja

全面理解Javascript中Promise

全面理解Javascript中Promise 最近在学习Promise的时候,在网上收集了一些资料,发现很多的知识点不够系统,所以小编特意为大家整理了一些自认为 比较好的文章,供大家更好地学习js中非常有趣的Promise Promise概念 2015 年 6 月,ECMAScript 6 的正式版 终于发布了. ECMAScript 是 JavaScript 语言的国际标准,javascript 是 ECMAScript 的实现.ES6 的目标,是使得 JavaScript 语言可以用来编写大

理解JavaScript中函数的使用

函数是进行模块化程序设计的基础,编写复杂的Ajax应用程序,必须对函数有更深入的了解. JavaScript中的函数不同于其他的语言,每个函数都是作为一个对象被维护和运行的.通过函数对象的性质,可以很方便的将一个函数赋值给一个变量或者将函数作为参数传递.在继续讲述之前,先看一下函数的使用语法: function func1(…){…} var func2=function(…){…}; var func3=function func4(…){…}; var func5=new Function(

深入理解JavaScript中的属性和特性

深入理解JavaScript中的属性和特性? JavaScript中属性和特性是完全不同的两个概念,这里我将根据自己所学,来深入理解JavaScript中的属性和特性. 主要内容如下: 理解JavaScript中理解对象的本质.理解对象与类的关系.对象与引用类型的关系 对象属性如何进行分类 属性中特性的理解 第一部分:理解JavaScript中理解对象的本质.理解对象与类的关系.对象与引用类型的关系 对象的本质:ECMA-262把对象定义为:无序属性的集合,其属性可以包含基本值.对象或者函数.即

JavaScript大杂烩6 - 理解JavaScript中的this

在JavaScript开发中,this是很常用的一个关键字,但同时也是一个很容易引入bug的一个关键字,在这里我们就专门总结一下页面中可能出现的this关键字(包括几种在其他页面文件中出现的this). JavaScript中的this关键字通常只使用在函数中,它指向当前函数的调用者,这是this关键字的本质,所有的使用方式都是围绕这个展开的,让我们来看一下在各种性质的函数中this的用法.1. 在对象的函数中使用this var person = { name: 'Frank', say: f

JavaScript中Object.prototype.toString方法的原理

在JavaScript中,想要判断某个对象值属于哪种内置类型,最靠谱的做法就是通过Object.prototype.toString方法. ? 1 2 var arr = []; console.log(Object.prototype.toString.call(arr)) //"[object Array]" 本文要讲的就是,toString方法是如何做到这一点的,原理是什么. ECMAScript 3 在ES3中,Object.prototype.toString方法的规范如下:

转载 深入理解JavaScript中的this关键字

转载原地址: http://www.cnblogs.com/rainman/archive/2009/05/03/1448392.html 深入理解JavaScript中的this关键字 1. 一般用处 2. this.x 与 apply().call() 3. 无意义(诡异)的this用处 4. 事件监听函数中的this 5. 总结 在JavaScript中this变量是一个令人难以摸清的关键字,this可谓是非常强大,充分了解this的相关知识有助于我们在编写面向对象的JavaScript程