原型
//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对象是谁构造出来的,Function
console.log(Object.__proto__===Function.prototype);//true
console.log(foo.__proto__===Foo.prototype);//true
console.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);//true
console.log(Function.prototype.constructor === Object);//flase
console.log(Object.prototype.constructor===Object)//true
console.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);//true
console.log(foo.__proto__.constructor === Foo)//true
console.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);//true
console.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);//function
console.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)//undefined
var 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);//true
console.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();//1
sub2.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();