js深入学习之原型及继承

1 篇文章 0 订阅

一:先来几个干货害羞

1 ,变量先声明后使用,使用未声明的变量会报错(大多程序语言使用未声明的变量都会报错,JS非严格模式使用未声明的变量,则会变成全局变量,严格(strict)模式也会报错)。
2,无(null)生万物,一切皆对象。(自然规律,JS貌似也遵守了,(js里的)null可以理解为指针对象是内存的一块区域,用于存储是对象)。
3,对象分为可执行对象(即函数对象)与不可执行对象(普通对象),对象拥有属性(特征)、方法(行为)。
4,对象的特殊属性:原型(prototype)、构造函数(constructor)、构造函数原型(__proto__,__proto__是constructor.prototype的简写)。
5,一切对象都有__proto__属性(null例外);只有函数对象有prototype属性。

6,程序语言的继承分为类继承和原型继承,JS的继承属于原型继承(此处所说的原型是__proto__不是prototype)。

二:再来一张图微笑

三:有图有干货开始干活了大笑(均在谷歌浏览器下测试)

    约定: (1)下文说的 XX的原型 都是通过 构造函数原型进行访问(constructor.prototype简写__proto__各大浏览器也是默认内置实现)。
              (2)对象原型是指Object构造函数原型:Object.prototype//({}.__proto__)===Object.prototype=>true;
                  数组原型是指Array构造函数原型:Array.prototype//Array.prototype===[].__protto=>true;
                  其他类型原型类同。

1、Object.ptototype(对象类型函数原型简称对象原型,下文同)是什么鬼。来个图看一下:

代码如下:
Object.prototype//对象类型函数原型

运行如下

2、看图验干货:

    1,对象原型的原型是null;(无声万物);
代码如下
Object.prototype.__proto__===null;//返回true,注意和Object.__proto的区别,自己可以可以看图猜测下。

运行如下

    2,对象分为可执行对象、不可执行对象(一切皆对象);
代码如下
Math.__proto__===Object.prototype//true
JSON.__proto__===Object.prototype//true
({}).__proto__===Object.prototype//true
Function.prototype.__proto__===Object.prototype//true;

运行如下:

    3,原型细分,类型原型产生(万物苏生ing.......);
代码如下
Boolean.__proto__===Function.__proto__//true
Number.__proto__===Function.__proto__//true
String.__proto__===Function.__proto__//true
Array.__proto__===Function.__proto__//true
Object.__proto__===Function.__proto__//true
Date.__proto__===Function.__proto__//true
RegExp.__proto__===Function.__proto__//true
Error.__proto__===Function.__proto__//true
Map.__proto__===Function.__proto__//true es6的类型
Set.__proto__===Function.__proto__//true es6的类型
Promise.__proto__===Function.__proto__//true es6的类型

运行如下

     4,错误原型再细分细分,错误开始分类(什么错都是错.......可怜);
代码如下:
EvalError.__proto__===Error//true
SyntaxError.__proto__===Error//true
TypeError.__proto__===Error//true
RangeError.__proto__===Error//true
URIError.__proto__===Error//true
ReferenceError.__proto__===Error//true

运行如下

     5,看完原型链开始看看它的继承吧(继承:你有的我都想有羡慕);
              1,继承的来源:prototype or __proto__(constructor.prototype);
代码如下:
//使数组都有pp方法;随即验证下prototype与__proto__属性
Array.pp=function(){
	console.info('prototye');
};
Array.prototype.pp=function(){
	console.info('__proto__');
}
[].pp()//->console.info('__proto__');
[].prototype//->undefined;
[].__prototype//->看下图

运行如下:

    6,熟悉完了prototype、__proto__看看constructor
               对象的consructor属性很简单就是指向其构建函数,愉快的举个栗子。
({}).constructor===Object//true;
({}).constructor.constructor===Function//true;
({}).constructor.constructor.constructor===Function//构造函数到Function是到尽头了,再怎么constructor都是Function本身
    7,学以致用,举栗子看继承(坚持:我是最后一个:奋斗抓狂);
function Parent(start) {
    this.name = 'parent的属性name';
    this.start = start;
}
Parent.prototype.do = function() {
    console.info('do-parent:');
};
Parent.prototype.say = function() {
    console.info('say-parent:');
};
Child.prototype.constructor = Child; //设置其构造函数。
/*使Child继承Parent的方式:**/
//<1>原型式继承:缺点是不能像起他语言那样像父类传递属性值
function Child(end) {
    this.name = 'child的属性name';
    this.end = end;
}

Child.prototype = new Parent(45);
Child.prototype.say = function() {
    console.info('Parent+Child:' + (this.start + this.end));
};
var a = new Child(55);
a.do();
a.say();
//类式继承:缺点是每次new Child都是不同实例不能共享公有方法。
function Child(end, start) {
    Parent.call(this, start);
    this.name = 'child的属性name';
    this.end = end;
}
Child.prototype.say = function() {
    console.info('Parent+Child:' + (this.start + this.end));
};
var a = new Child(45,55);
a.do(); //=>a.do不是一个函数
a.say();
//混合式:原型式继承和类式继承一起使用。
function Child(end, start) {
    Parent.call(this, start); //第二次条用,开始关注其实例属性。
    this.name = 'child的属性name';
    this.end = end;
}
Child.prototype = new Parent(); //第一次条用;仅仅是获取它的原型方法,对于其属性无关紧要;
Child.prototype.say = function() {
    console.info('Parent+Child:' + (this.start + this.end));
};
var a = new Child(45,55);
a.do();
a.say();
//寄生式混合继承:因为混合继承的第一次条用父Parent的时候不关注其实例属性,仅仅是获取其父上的方法。
//如果Parent的构造函数足够复杂的时候会造成资源浪费,性能降低。所以可以用一个空的构造函数进行过渡。
/**es5中Object.create实现了create函数,es5中可以Object.create或者用Object.setPrototypeOf*/
var create = function(proto) {
    function A() {}
    A.prototype = proto;
    return new A();
};

Child.prototype = Object.create(Parent.prototype)||create(Parent.prototype);
//或者直接设置其原型Object.setPrototypeOf(Child,Parent.prototype)
Child.prototype.say = function() {
    console.info('Parent+Child:' + (this.start + this.end));
};
var a = new Child(55, 45);
a.do();
a.say();
//es6快捷语法类继承。
class Parent {
    constructor(start) {
        if (start) {
            this.start = start;
        }
    }
}
Parent.prototype.do = function() {
    console.info('parent-do');
};
class Child extends Parent {
    constructor(end, start) {
        super(start);
        this.end = end;
    }
}
Child.prototype.say = function() {
    console.info('Parent+Child:' + (this.start + this.end));//属性也继承了.
};
var a=new Child(45,55)
a.do();//方法继承
a.say();


总结:

    终于写。。。完玩了,陆陆续续整理、写贴花了两三天时间,第一次写贴不足的地方勿喷多指教。都是自己总结的不对的地方欢迎指正。QQ:512157407(凤凰)
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值