Javascript对象和原型继承的理解

来源:互联网 发布:淘宝店全包 编辑:程序博客网 时间:2024/04/29 23:15

如果学过java或者c++,那一定认为继承应该是class类型的,在此基础上接触javascript的继承,一定会有点小困难。现在的自己也不能说是很了解,至少还没有理解,为啥大神们说基于原型的继承会比基于类的继承更强大?
先罗列一下资料,
MDN中文版
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
秘密花园
https://bonsaiden.github.io/JavaScript-Garden/zh/#function.general
还有一本书,javascript语言精粹。
还看到一篇不错的文章 http://developer.51cto.com/art/201107/274575.htm

好吧,开始。
对于继承这个事,要有个父类。java中的鼻祖是Object,而Javascript也是Object。但又有点区别,后面说。
java中分为类和对象,类对应class字节码,对象则是对类进行new出来的产物,期间会调用构造对象。javascript则一切混淆的多了,一切都是对象了。比如,声明对象的方式有
第一种:
var obj = new Object();
或者var object = Object.create();
第二种:
var obj1 = {};
第三种:
function f() {}
var obj2 = new f();
第二种,其实是第一种的语法糖,也是利用了Object方式。但其实终归是使用了第三种。new也只是针对function的操作符。有个例子可以作证:
var obj = {};
obj.constructor; //返回 [Function: Object]
也就是说Object是构造函数。
那,这里就有个问题了,Function和Object是啥关系呀?鸡和蛋的关系,sorry,我没有完全搞明白。

继承要注意几个属性,prototype,proto, constructor。这里没有类型和对象的概念,相对来说,有对象和实例。
继承是通过原型链实现的。
区分几个概念:
1. prototype属性是针对Function对象的,也就是function函数的属性。prototype属性指向它的原型对象,原型对象有constructor属性。
2. proto属性,是每个对象都会有的,包括函数对象。这个属性指向对象对应的类型的prototype对象。
比如,function f() {}
var obj = new f();
obj.proto,指向 f.prototype,而f.prototype.constructor 指向 f本身。
再引申一下,f是Function对象new出来的实例,f.proto,指向Function.prototype对象.
原型链就是根据proto,连接到它的原型对象,也就是通过这个属性实现它的继承关系。访问一个对象的属性,如果不存在,则会在它proto指向的原型对象中寻找,找到就返回,找不到的话则会顺着proto链一直找下去。

=======================================
再好好的研究一下这个文档
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

Each object has an internal link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype. null, by definition, has no prototype, and acts as the final link in this prototype chain.
每个对象都会有自己的原型对象,原型对象也有自己的原型,直到原型为null。这个叫原型链。
对象获得自己的原型有两种方式,obj.proto 或 Object.getPrototypeOf(obj)。
关键是搞清楚谁是原型对象,下面不同的对象构造方式,对应不同的原型链。
比如:

var o = {a: 1};原型链为:o --> Object.prototype --> null

函数对象

function f(){  return 2;}// Functions inherit from Function.prototype // (which has methods like call, bind, etc.)// f ---> Function.prototype ---> Object.prototype ---> null

使用Object.create(obj)的继承方式的prototype

var a = {a: 1}; // a ---> Object.prototype ---> nullvar b = Object.create(a);// b ---> a ---> Object.prototype ---> nullconsole.log(b.a); // 1 (inherited)var c = Object.create(b);// c ---> b ---> a ---> Object.prototype ---> nullvar d = Object.create(null);// d ---> nullconsole.log(d.hasOwnProperty); // undefined, because d doesn't inherit from Object.prototype

能够分析出原型链的各个环节是最重要的!

0 0
原创粉丝点击