老是据说面向对象,类,继承,__proto__,prototype,constructor.......因而乎小整理一下。html
首先说,JS里的继承是怎么弄的呢?函数
首先建立类(Person)学习
var Person = { male: 0, age:0, name:'nothing', say:function(){ console.log('Hello World'); } }
如何建立一我的呢?this
var createPerson = function(){ return Object.create(Person); }
建立学生.net
var Student = createPerson(); Student.say() //Hello World Student.__proto__ === Person //true Student.constructor === Person //Student的构造器仍是Object
从这个能够看出什么呢?能够看出所谓的继承,就是下面的代码而已:prototype
SSSSS.__proto__ = BBBBB
可是呢?也没有prototype啥关系嘛,由于压根就和他不要紧,好像也不太好,换一种写法好了。code
function Person (props){ this.name = props.name || 'nothing'; this.male = props.male || 0; this.age = props.age || 0; this.say = function(){ console.log('Hello world!'); } }
继续建立studenthtm
var Student = new Person(); Student.__proto__ === Person.prototype //true Student.constructor === Person //true Student.say() //Hello world!
从上面代码能够看出,Student继承了Person.
若是咱们想改变一下呢?对象
Student.say = function(){ console.log('Hello teacher, my name is ' + this.name);//Hello teacher, my name is nothing }
那好,再建立一个coder类blog
var Coder = new Person(); Coder.say(); //Hello world!
这个不错嘛,这样在想建立Coder的子类,js和html,那就修改一下代码
function Coder (props){ Person.call(this,props); this.tip = props.tip?props.tip.toUpperCase():''; this.intro = function(){ console.log('I know '+(this.tip?this.tip:'nothing')); } this.say= function(){ console.log('hello, my name is ' + this.name); } } var JSer = new Coder({ name:'Tony', age:26, tip:'js' }); var htmler = new Coder({ name:'Jermy', age:26, tip:'html' }); JSer.say(); //hello, my name is Tony htmler.say(); //hello, my name is Jermy JSer.intro(); //I know JS htmler.intro();//I know HTML
这样获得了咱们想要的结果,验证一下继承关系:
JSer instanceof Coder; //true htmler instanceof Coder;//true Coder instanceof Person;//false
这样就很差了,为何不是继承关系呢?查看一下Coder状况如何?
Coder.__proto__ === Person.prototype; //false Coder.__proto__ //function () { [native code] }
看来问题就出在这里,写一个中间函数补充一下?
var pass = function(child,parent){ var F = function(){}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; }
为了实现这一点,参考道爷(就是发明JSON的那个道格拉斯)的代码,中间对象能够用一个空函数F来实现,大神写的代码,就是特么让人深思。
仔仔细细想了下,我我的是这么理解的。
首先定义空函数这个不用解释,而后把这个空函数的原型指向为Parent的原型,而后再把Child的原型指向这个新的F对象,一个完美传递;
最后,在把Child原型的构造方法定义成Child;
华丽的转身,结果以下:
function Coder (props){ Person.call(this,props); this.tip = props.tip?props.tip.toUpperCase():''; this.intro = function(){ console.log('I know '+(this.tip?this.tip:'nothing')); } this.say= function(){ console.log('hello, my name is ' + this.name); } } var pass = function(Child,Parent){ var F = function(){}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; } pass(Coder, Person); var JSer = new Coder({ name:'Tony', age:26, tip:'js' }); var htmler = new Coder({ name:'Jermy', age:26, tip:'html' }); JSer.say(); //hello, my name is Tony htmler.say(); //hello, my name is Jermy JSer.intro(); //I know JS htmler.intro();//I know HTML JSer instanceof Coder; //true htmler instanceof Coder;//true Coder instanceof Person;//false
结果仍是不对,因而我又在大神的肩膀上垫了一下脚。
var pass = function(Child,Parent){ var F = function(){}; F.prototype = Parent.prototype; Child.__proto__ = new F(); Child.__proto__.constructor = Child; }
结果就正确了......
又查了一下,总结一下:
全部的对象都有__proto__属性,该属性对应该对象的原型.
全部的函数对象都有prototype属性,该属性的值会被赋值给该函数建立的对象的_proto_属性.
全部的原型对象都有constructor属性,该属性对应建立全部指向该原型的实例的构造函数.
函数对象和原型对象经过prototype和constructor属性进行相互关联.
虽然说弄懂了些表面的东西,实际上最主要的缘由仍是没明白,那就是原型链到底有什么用呢?
好了,以上就是今天总结的一些内容,但愿相互学习帮助,可以在将来更好的工做生活。
信息来源:
(↓相关一些对我帮助很大,Git的学习就是在这里看的,说的很详细也很生动↓)
廖雪峰JavaScript教程
JS原型、原型链深刻理解
深刻分析js中的constructor 和prototype