值得一说的是对象没有prototype属性,只有函数有prototype属性。

  1. var a = function(){};
  2. a.prototype.d = function(){
  3. console.log();
  4. }

prototype相当于给函数a添加了一个属性。

  1. var a = function(){};
  2. a.prototype.d = function(){
  3. console.log();
  4. }
  5.  
  6. var b = new a();
  7. b.d(); //

用prototype添加的属性,实例化后这个函数的对象也可以继承这个属性。

那为什么要用prototype添加属性呢?来看看

  1. var a = function(){
  2. var f = function(){
  3. console.log();
  4. }
  5. };
  6.  
  7. var b = new a();
  8. b.f(); //报错

  为什么报错?先看一下call方法和new对象的关系这篇文章,看完你就明白b可以继承函数a的prototype属性了。

  注意我那篇文章只说的了new可以继承prototype属性,但是没有说它可以继承函数里面的内容。所以为什么解决这个为什么我们就会用到prototype了,当然有时为了一些优化的原因也会这样用。

  其实不只是prototype可以解决这个问题,还有this也是可以解决这个问题的,就像我们使用构造函数一样,我们都是用的this对吧,因为new以后就会改变这个this的指向,然后这个属性就会变成你创建出来的那个对象的属性。  对于this的指向问题可以看彻底理解js中this的指向,不必硬背。

  1. function Fn(){
  2. this.num = ;
  3. }
  4. var a = new Fn();
  5. console.log(a.num); //

  那么__proto__是什么?为了更好的理解__proto__建议你先看什么是作用域链这篇文章。

  __proto__和作用域的行为类似,只不过__proto__是对于对象的属性来说的,而作用域链是对于变量来说的,什么意思?就是说一个对象如果要打印这个对象的某个属性,那么它会先在自己的对象中查找,如果没有找到那么它就会__proto__中找,看看有没有这个属性。那么__proto__中到底有哪些属性?

  你一开始创建的对象__proto__指向了obj.__proto__,也就说明我们创建的任何对象都可以调用obj.__proto__里面的属性和方法,而obj的__proto__为null,也就是说到obj的__proto__就到头了。这也就是说如果我们没有做任何的操作,这个对象只能继承obj.__proto__的属性,这里没有算上obj的__proto__是因为,obj的__proto__为null。

  但是如果我们用了new操作符实例化了一个函数,那么这个new出来的对象就又多了一个继承对象,那就是那个构造函数。而这个构造函数如果用prototype添加属性同样的,这个实例化的对象也可以继承它的属性。

  还有一点就是如果这个对象本身就有这个属性就不会去继承,继承只有在这个对象没有找到的时候才会继承,就和我们学css的继承样式一样。

  1. function Fn(){
  2.  
  3. }
  4. Fn.prototype.num = ;
  5. var a = new Fn();
  6. a.num = ;
  7. console.log(a.num); //

如果这个对象没有这个属性才会继承,并且这个对象有多个__proto__那么它也只是继承最近的那个属性。

  1. function Fn(){
  2.  
  3. }
  4. Fn.prototype.num = ;
  5. var a = new Fn();
  6. console.log(a.num);

在这段代码中Fn的__proto__离对象a最近所以继承它的,而不是obj的。

补充一点:

  1. function Foo() {};
  2. var foo = new Foo();
  3. Foo.prototype.num = ;
  4. console.log(foo.num); //52
  5. console.log(Foo.num); //undefined

再看

  1. function Foo() {};
  2. var foo = new Foo();
  3. Foo.prototype.num = ;
  4. console.log(foo.num); //
  5. console.log(Foo.prototype.num); //

对,你没有猜错,num只是prototype的属性,而prototype是Foo的属性,自然只能通过Foo.prototype.num来访问这个属性,那么为什么new出来的对象可以不用加prototype就可以访问num呢?

实际上new出来的对象是这样的。

  1. var fn = function(a){
  2. this.a = a;
  3. }
  4. var obj = {};
  5. 继承
  6. obj.__proto__ = fn.prototype;
  7. 改变this指向
  8. fn.call(obj);

看到没有,已经写了fn.prototype,自然就可以在后面点那个属性了。ok了吧?

__proto__与prototype的更多相关文章

  1. 谈谈__proto__和prototype的区别

    我想javascript中的原型链一直想很多初学javascript的同学感到非常的困惑,今天看了一些文章,结合自己的理解,把原型链这个东西从新来整理一下,如有不对之处,望大家帮忙指出. 首先,我们应 ...

  2. JavaScript中__proto__与prototype的关系

    一.所有构造器/函数的__proto__都指向Function.prototype,它是一个空函数(Empty function) 1 2 3 4 5 6 7 8 9 Number.__proto__ ...

  3. intanceof以及引出的__proto__和prototype

    instanceof运算代码 function instance_of(L, R) { //L 表示左表达式,R 表示右表达式 var O = R.prototype; // 取 R 的显示原型 L ...

  4. 15条规则解析JavaScript对象布局(__proto__、prototype、constructor)

    大家都说JavaScript的属性多,记不过来,各种结构复杂不易了解.确实JS是一门入门快提高难的语言,但是也有其他办法可以辅助记忆.下面就来讨论一下JS的一大难点-对象布局,究竟设计JS这门语言的人 ...

  5. javascript--15条规则解析JavaScript对象布局(__proto__、prototype、constructor)

    大家都说JavaScript的属性多,记不过来,各种结构复杂不易了解.确实JS是一门入门快提高难的语言,但是也有其他办法可以辅助记忆.下面就来讨论一下JS的一大难点-对象布局,究竟设计JS这门语言的人 ...

  6. Javascript中的__proto__、prototype、constructor

    今天重温了下Javacript,给大家带来一篇Javascript博文,相信对于Javacript有一定了解的人都听过prototype原型这个概念,今天我们深度的分析下prototype与__pro ...

  7. js中Object.__proto__===Function.prototype

    参考:http://stackoverflow.com/questions/650764/how-does-proto-differ-from-constructor-prototype http:/ ...

  8. javascript中的__proto__和prototype

    一.2个参考网址: http://icekiller110.iteye.com/blog/1566768 http://www.cnblogs.com/snandy/archive/2012/09/0 ...

  9. 关于 __proto__和prototype的一些理解

    var Person = function(name) {}; Person.prototype.say = function() { console.log("Person say&quo ...

随机推荐

  1. iOS开发——高级技术&通讯录服务

    通讯录服务 AddressBook iOS中带有一 个Contacts应用程序来管理联系人,但是有些时候我们希望自己的应用能够访问或者修改这些信息,这个时候就要用到 AddressBook.frame ...

  2. LICEcap – 灵活好用,GIF 屏幕录制工具

    LICEcap – 灵活好用,GIF 屏幕录制工具 http://www.appinn.com/licecap/

  3. 屏蔽iOS10模拟器海量的垃圾debug信息

    屏蔽iOS10模拟器海量的垃圾debug信息 不屏蔽之前 进行如下设置 OS_ACTIVITY_MODE = disable 即可屏蔽垃圾信息

  4. Android布局优化之过度绘制

    如果一个布局十分复杂,那么就需要来排查是否出现了过度绘制,如果出现了,那么很可能会造成刷新率下降,造成卡顿的现象.那么什么是过度绘制呢?过度绘制就是在同一个区域中叠加了多个控件.这就像小时候我们画画, ...

  5. 永久删除 tadb.exe

    系统安装qq手机管家等手机管理软件之后,在开机时会自动运行tadb.exe, 这个垃圾进程会让开发android程序时默认的 adb.exe启动不了,这样就没法用手机调试. 这并不是说tadb.exe ...

  6. vi命令示例大全

    1.      进入vi l vi filename: 打开或新建文件,并将光标置于第一行首 l vi +n filename:打开文件,并将光标置于第n行首 l vi + filename:打开文件 ...

  7. Mac Port 基本用法总结

    Mac Port 基本用法总结 Mac Port 基本用法总结 1. Mac Port的下载地址 http://www.macports.org/install.php 2. Mac Port的说明文 ...

  8. ubuntu(Mint-17)修改dns

    国内默认dns常被劫持,所以需要修改: $ sudo vi /etc/network/interfaces 在下面添加一行: dns-nameservers 8.8.8.8 8.8.4.4 然后,网上 ...

  9. 同时大量PPPoE连接请求,攻击PPPoE服务器,导致的用户异常掉线故障分析

    前几天接一个客户电话,PPPoE下用户异常掉线,掉线后拨号困难 到达后,我首先查看PPPoE日志,发现一秒钟内有大量PADI包,浪费服务器的SESSION,同时让服务器无法处理其他用户的请求. 打开W ...

  10. JS表单设置值

    //表单设置值 $.fn.setForm = function(jsonValue) { var obj = this; $.each(jsonValue, function (name, ival) ...