打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
js 对象布局

总结起来基本上:

第一点: 关于prototype , __proto__
前者是构造器才有的,后者是每个实例对象所有的。

假设f 是F的实例,而F是一个构造器(js中称那些模拟class的函数叫做构造器)

那么

f.__proto__ 就是 F.prototype

而F.prototype 必然也是某个XXX 的实例 ;


比如

function Bar()

{

}


var bar = new Bar();

那么bar.__proto__ 就是Bar.prototype  就是Object 的一个实例o(假设Bar没有做特别设置)

o.__proto__ 就是Object.prototype 

而Object.prototype.__proto__ === NULL



第二点constructor

每个构造器的prototype的特殊属性

这个constructor实际上就是指向自己,比如Bar.prototype.constrcutor === Bar

比较像是传统意义上的class 而不是instance。


由于修改prototype实现继承时候,并不自动完成这个属性的修改,所以需要自己修改:


  1. function Foo(){}  
  2. var foo=new Foo();  
  3. function Bar(){  
  4.     this.constructor=Bar;  
  5. }  
  6. Bar.prototype=foo;  
  7. var bar=new Bar();  
  8. bar.constructor //Bar  

Javascript的原型链探究

by zmmbreeze on 1010/08/30

本来想写一篇“如何用JS实现面向对象”,发现自己对prototype原型链还是有很多的不理解的地方。先看一张原型链关系图:

prototype属性

prototype是所有函数都有的一个属性

1
2
3
function Man(){
}
console.log(Man.prototype); //Object{ }

prototype 属性使您有能力向对象添加属性和方法。在每个使用每个对象的属性或方法时,js会按照原型链的顺序查找属性,直到找到。

1
2
3
4
5
6
7
8
9
10
11
12
13
function employee(name,job,born)
{
this.name=name;
this.job=job;
this.born=born;
}
var bill=new employee("Bill Gates","Engineer",1985);
employee.prototype.salary=null;
bill.salary=20000;
console.log(bill.salary); //20000

注意对象是没有prototype属性的,只有函数有。但是一些特有的浏览器(firefox,chrome)通过__proto__属性暴露了原型prototype,如上图。

new关键字

new用于新建一个对象,例如:

1
2
3
function Man(){
}
var m = new Man();

下面的代码用js模拟了new操作:

1
2
3
4
5
6
7
8
9
function newObj(Fun,arguments) {
    var o = {};
    if (Fun && typeof Fun === "function") {
        o.__proto__ = Fun.prototype;
        o.prototype = Fun;
        Fun.apply(o, arguments);
        return o;
    }
}

从代码中可以看出,首先新建一个对象o,然后修改__proto__指??Fun.prototype,然后以o为上下文(context)执行Fun函数,最后返回o。因为对象的__proto__设置是在new操作中的,所以导致了以下现象:

1
2
3
4
5
6
7
8
function Man(){
}
function Father() {
    this.name=""
}
var m = new Man();
Man.prototype = new Father();
console.log(m.name); //undefine

 

至此我们理解了图中的第一层,接下来讲第二、三层。

为何Foo.__proto__ !== Foo.prptotype?

这里Foo函数可以看成是Function函数的对象!按照图中第一层的逻辑:对象的__proto__指向其函数的prototype属性,Foo的__proto__应该等于Function.prototype。

那么为什么Function函数和Object函数的__proto__都等于Function.prototype呢?

注意Function和Object都是函数,而所有的函数都是Function函数的对象(有点绕)!所以同上,它们的__proto__应该等于Function.prototype。

为什么o1与o2的__proto__等于Object.prototype呢?

原因与第一层的结构一样,o1,o2是Object函数的对象。

注意了:Function.prototype与Foo.prototype同样是对象,它们也是通过Object函数构建的,所以它们的__proto__也等于Object.prototype

Object.prototype

Object.prototype值是无法修改,它提供了一些默认的方法。且它的__proto__等于null!

1
2
3
4
5
function Man(){
    this.oo = "11";
}
Object.prototype = new Man();
console.log(Object.prototype.oo); //undefine

 

理解Javascript的原型链的重点在于:对象、函数、函数的prototype,函数与函数的prototype同时也是对象

在JavaScript语言中,一切的一切都是对象,它们全部继承自Object. 或者说所有对象的原型链的根节点都是Object.prototype。

 

instanceof操作符

instanceof是一个二元运算符,如:A instanceof B. 其中,A必须是一个合法的JavaScript对象,B必须是一个合法的JavaScript函数 (function). 判断过程如下:

  如果函数B在对象A的原型链 (prototype chain) 中被发现,那么instanceof操作符将返回true,否则返回false.

所以导致了:

1
2
3
4
Function instanceof Object;//true
Object instanceof Function;//true
Function instanceof Function;//true
Object instanceof Object;//true

这样的情况发生!

zmmbreeze0825@gmail.com

There are 3 comments in this article:

  1. 31/08/2010zsx says:

    有听过prototype和chains of responsibility两种模式,那么原型链与其有什么关系呢?

  2. 31/08/2010swinging says:

    @

    zsx

     


    原型设计模式:在clone之后,原型的修改不会反应到新生成的clone对象上,而js则会反应到所有对象上,更像是静态属性或静态方法那种情况。

    责任链设计模式和原型链一样。js在查找对象属性时,首先在本对象查找,如果没有就查找其prototype,依次将属性名传递下去,知道找到对应的属性。

    这个也不错!

    http://driftcloudy.iteye.com/blog/907177

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
JavaScript是如何面向对象的
深入理解javascript原型和闭包(6)
JavaScript 面向对象编程
JavaScript的原型系统是怎样构建起来的
详解prototype与
js 原型链
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服