原型

//new Function() /*所有函数都是通过new Function构造出来的,所以函数也是实例对象,由Function创建出来的实例对象*/// function Foo(){// }var Foo=new Function();//与上面function Foo意思一样var foo=new Foo();console.log(Foo.__proto__===Function.prototype);//true Foo对象是谁构造出来的,Functionconsole.log(Object.__proto__===Function.prototype);//trueconsole.log(foo.__proto__===Foo.prototype);//trueconsole.log(Foo.__proto__===Foo.prototype)//false
访问原型的方式有两种:
1.实例对象.proto
2.构造函数.prototype
实例对象.proto===生成此实例对象的构造函数.prototype
构造函数.prototype,也是一个对象
构造函数也是函数,都是一样的声明方式
函数也是对象,都是new Function创建出来的实例对象,对象就是实例对象
const sum = new Function('a', 'b', 'return a + b');console.log(sum(2, 6));// expected output: 8
console.log(Object.__proto__===Function.prototype);//true//var obj=new Object();/*Object可以new出来,Object也是构造函数,也是函数,函数也是对象,Object是默认的构造函数Function可以创建函数,构造函数,可以创建构造函数的构造函数,可以创建实例对象的实例对象相当于Object实例对象.__proto__与生成Object实例对象的构造函数Function相等,证明Function是Object实例对象的构造函数*/
Function创建的实例对象还是构造函数,Object不行,创建的是对象
// var foo=new Foo();// new foo()//错误// var obj=new Object();// new obj()//错误var func=new Function();console.log(new func());//{}
Constructor
constructor是原型上才有的属性,它指向的是对应实例的构造器
console.log(Function.prototype.constructor === Function);//trueconsole.log(Function.prototype.constructor === Object);//flaseconsole.log(Object.prototype.constructor===Object)//trueconsole.log(Object.prototype);console.log(Object.constructor === Function);//true/*因为只有prototype中才有原型,所以Object没有原型,Object.操作是把Object当成是一个对象来操作,*/console.log(Object.__proto__.constructor === Function)//true
因为只有prototype中才有原型,所以Object没有原型,Object.操作是把Object当成是一个对象来操作,找Object对象中有没有constructor属性,但Object上没有,所以查找原型链上有没有,Object.proto就是Function.prototype,所以就变成了Function.prototype.constructor===Function,就是Object.proto.constructor === Function
就是实例对象.constructor===构造实例对象的构造函数
function Foo() {}var foo=new Foo();console.log(foo.constructor===Foo);//trueconsole.log(foo.__proto__.constructor === Foo)//trueconsole.log(foo.prototype.constructor===Foo)
不是函数没有constructor,不能.prototype
function Foo() {}console.log(Foo.__proto__)//Function构造函数
内置函数,打印看不见
function Foo() {}var foo=new Foo();console.log(Function.__proto__===Function.prototype);//trueconsole.log(foo.__proto__===Foo.prototype);//true
Function是实例对象,同时Function也是构造函数
console.log(Function.prototype.__proto__===Object.prototype);//true
Function.prototype是对象.proto===构造函数Object.prototype
console.log(typeof Object);//functionconsole.log(typeof Function);//function
console.log(Object.prototype);//原型的终点console.log(Object.prototype.__proto__);//null
为什么是null,不是undefined? 因为b未定义,未赋值undefined,如下
var obj={a:1}console.log(obj.b)//undefinedvar c;console.log(c)//undefined
而proto定义了,并且赋值了,为null
var c=null;console.log(c)
var c=null;console.log(c)//null
通过get、set方法赋值
var t=null;t=setInterval(function() {},1000);var obj={a:1,get b(){return 2;}}console.log(obj.b)//2
console.log(Object.__proto__===Function.prototype);//trueconsole.log(Object.__proto__===Object.prototype)//false
只有Function既是函数,又是对象,相等其它的都像Object一样不相等,Object也是既是函数又是对象,只要是函数都是既是函数又是对象,但对象不一定是函数
console.log(Function.prototype.__proto__===Object.prototype);//true Object.prototype是原型链的终点
原型链继承
原型继承实例对象

原型链继承 引用值共享的问题
Call继承:借用构造函数
function Super(){this.a=[1,2,3,4];}Super.prototype.say=function() {console.log(1);}function Sub() {// Super.call(this);}Sub.prototype=new Super()var sub1=new Sub();var sub2 = new Sub();// sub1.a='3333';//不会影响sub1.a.push(5);console.log(sub1.a);console.log(sub2.a);

解决方法:借用构造函数
function Super(){this.a=[1,2,3,4];}Super.prototype.say=function() {console.log(1);}function Sub() {Super.call(this);}// Sub.prototype=new Super()var sub1=new Sub();var sub2 = new Sub();sub1.a.push(5);console.log(sub1.a);console.log(sub2.a);

但是会出现,父类原型方法无法获取的问题
组合继承
红宝书上的(伪经典继承)
function Super(){this.a=[1,2,3,4];}Super.prototype.say=function() {console.log(1);}function Sub() {Super.call(this);}Sub.prototype=new Super()var sub1=new Sub();var sub2 = new Sub();sub1.a.push(5);console.log(sub1.a);console.log(sub2.a);
经典继承
寄生组合继承
也不是很好的解决父原型上的继承;
YUI雅虎就是这么写的
function Super(){this.a=[1,2,3,4];}Super.prototype.say=function() {console.log(1);}function Sub() {Super.call(this);}// Sub.prototype=new Super()sub.prototype=Object.create(Super.prototype);//比new Super()没有this.a的参与,this.a在Super.call(this);参与//sub.prototype.__proto__=Super.prototype;//相当于//Object.getPrototypeOf(Sub.prototype)=Sub.prototype; //错误var sub1=new Sub();var sub2 = new Sub();// sub1.a.push(5);// sub1.a='3333';console.log(sub1.a);console.log(sub2.a);sub1.say();//1sub2.say();//1
function Super() {this.a = [1, 2, 3, 4];}Super.prototype.say = function () {console.log(1);}function Sub() {Super.call(this);}// Sub.prototype=new Super()// Sub.prototype=Object.create(Super.prototype);// Object.getPrototypeOf(Sub.prototype)=Sub.prototype;// sub.prototype.__proto__=Super.prototype;//es版本低,没有Object.create方法if (!Object.create) {Object.create = function (proto) {var F = function () { };F.prototype = proto;return new F();}}Sub.prototype.say2 = function () {console.log(333333);}//会被Sub.prototype = Object.create(Super.prototype);所覆盖,得不到应用Sub.prototype = Object.create(Super.prototype);Sub.prototype.say2 = function () {console.log(333333);}var sub1 = new Sub();var sub2 = new Sub();// sub1.a.push(5);// sub1.a='3333';console.log(sub1.a);console.log(sub2.a);sub1.say();sub2.say();sub1.say2();
圣杯继承
圣杯模式也是重写了原型,重新覆盖了原型,也是之前写的得不到应用
class继承
比较好,es6方式是最完美的解决方式
许多框架用的别的,还有更多的继承方式
如拷贝继承用的人很少
class Super{constructor() {this.a=[1,2,3,4];}say2(){console.log(22222);}}class Sub extends Super {say1() {console.log('1111111');}}var sub1=new Sub();var sub2=new Sub();// sub1.a='3333';console.log(sub1.a);console.log(sub2.a);sub1.say1();sub1.say2();
私有成员es7
class Super{//a=[1,2,3,4];constructor() {this.a=[1,2,3,4];}say2(){console.log(22222);}}class Sub extends Super {// b=[5,6,7,8];//相当于 私有成员变量 成员属性constructor(){super();this.b=[5,6,7,8];}say1() {console.log('1111111');}}var sub1=new Sub();var sub2=new Sub();// sub1.a='3333';console.log(sub1.b);console.log(sub2.a);// sub1.say1();// sub1.say2();

class Super {constructor () {this.a = [1, 2, 3, 4];}say2() {console.log(22222);}}class Sub extends Super {// b=[5,6,7,8];//相当于 私有成员变量constructor () {super();this.b = [5, 6, 7, 8];}say() {console.log('prototype');}static say1() {console.log('static');}}//相当于如下,var sub1 = new Sub();var sub2 = new Sub();// sub1.a='3333';console.log(sub1.b);// console.log(sub2.a);sub1.say();Sub.say1();

相当于
function Sub() {this.a = [1,2,3];}Sub.prototype={say:function() {console.log('prototype')}}Sub.say1=function() {console.log('static')}var sub1=new Sub()sub1.say();Sub.say1();

静态方法
Object.getPrototypeOf();Array.from();[].sort();[].indexOf();

