第十四章 命令行和原型

162 阅读13分钟

一、DOS命令窗口

1、打开dos命令窗口的几种方法:

  • window+r ==》输入cmd
  • 在资源管理器的当前路径上直接输入cmd
  • 鼠标右键 git bash here

2、常用的dos命令

dos是Linux写的,用c开发的,我们先来说下Linux常用的一些命令

  • 打开对应的文件夹:cd 文件夹 (首先要确定当前目录下有该文件夹)
    比如: C:\Users\Administrator\Desktop\test>cd a.txt
  • 回退到上一级:cd ../
  • 查看当前目录下的文件夹:cd + tab
  • 返回到根目录:cd + /
  • 创建一个文件夹:mkdir + 文件名
  • 创建一个文件:copy con 文件名.txt, 然后按回车,键入想要输入的内容“新建文件”,结束后回车按ctrl + z
  • 重命名一个文件或者文件夹:rename b f
  • 删除一个文件夹:rd + 文件夹名(只能删除空的文件夹)
  • 删除一个文件夹:rd + /s + 文件夹名 (硬删除,即使里边有内容也能删除)
  • 清空命令行:cls
  • 切换磁盘命令:D:/F:/C: 切换到相应的盘符

Mac本:如果不想一个个敲路径,可以用:cd + 把文件拖过来 自动生成此路径

二、git版本控制系统

1、git(版本控制);git是什么,git又是做什么的

1.1 git简介

  • 就是一个代码的管理工具(github gitee码云 gitlab 代码的远程存储仓库)

1.2 git作用

  • 记录历史版本信息
  • 方便团队之间协作开发

1.3 git使用

  • git config --global user.name "renjinhui"
  • git config --global user.email "1227760869@qq.com"
  • 从远程仓库中复制以上两条代码,用来告诉本机的git工具 告诉本机:我是谁

2、国内常用的版本控制系统

1、git:分布式管理系统

特点:

  • 每台电脑都是一个服务器,即使中央服务器坏了,版本信息都在每个人的电脑上了
  • 如果不需要合作开发,不用中央服务器的前提下,不需要联网也可以进行版本控制
  • 文件上传是以文件流的形式,速度快

2、svn:集中式版本管理系统

特点:

  • 属于集中式版本控制,需要一个专门的中央服务器,如果这台服务器瘫痪了,代码就找不回来了
  • 无论干啥都要联网
  • 上传代码的时候是以文件的形式,速度比较慢

 3、git的安装:

    > git官网  git-scm.com/downloads

    > 安装成功后在桌面右键会出来两个git选项(打开git bash here,然后执行git --version)

    > GIT是linux创始人研发的工具,所以GIT中的操作大部分都是linux操作命令

4、git的工作原理(分为三个区)

  • 工作区:我们平时写代码的区
  •  暂存区:用来临时存储代码
  •  历史区:生成历史版本

5、 git的使用

git的全局配置

  •  git config --global --list:查看全局配置信息
  •  git config --global user.name 'xxx'  
  • git config --global user.email 'xxx@xxx'

6、创建本地仓库,完成版本控制

6.1、创建本地仓库

  • git init(会默认生成一个.git文件夹,这里是存放你本地git仓库的信息的,不能删除)
  • shift + cmmand + .  mac电脑显示隐藏目录

\

6.2、在工作区编写代码完成后,提交到暂存区

  • git add 文件名(把指定文件提交到暂存区)
  • git add A(把工作区所有文件提交到暂存区)
  • git add . (把工作区所有修改的和新增的文件提交到暂存区,不包括删除的)
  • git status(查看当前文件提交状态)【红色代表在工作区;绿色代表在暂存区;没有文件,并显示clear之类的单词,说明文件已经提交到历史区或者没有任何更改】
  • clear:清屏

6.3、把文件提交到历史区

  • git commit -m'描述' (把文件提交到历史区,并生成此次提交的历史版本)
  • git log(查看提交的历史版本信息,不包括回滚)
  • git reflog(查看所有的历史版本信息,包括回滚信息)

\

6.4、回滚指定历史版本的代码

  • git reset --hard 七位历史版本号

7、远程仓库的使用

    7.1、介绍远程仓库github

  • github是一个开源的代码分享平台;每一个github账户都可以把自己的代码分享到这个平台上,那他就是充当中央服务器的角色,把代码提交到这个平台上之后,你可以在任何一个有网络的地方去下载代码,还可以配置下载的权限

    7.2、创建一个远程仓库(点击左上角绿色的按钮 New)

  • Repository name:新建仓库的名称
  • Description:新建仓库的描述
  • Public/Private:新建仓库是公开还是私密的
  • Initialize this repository with:为仓库增加初始化文件(暂时不选)
  • 绿色按钮 Create repository: 创建新的仓库

    7.3、把本地仓库的代码提交到远程仓库

  • 本地仓库和远程仓库建立连接
    •  git remote -v(查看本地和远程仓库的连接状态)
    • git remote add origin 远程仓库地址(和远程仓库的某个新项目建立连接,origin这个名可以改,但是大 家都统一叫这个)
  • git pull origin master (拉取远程仓库的代码到本地)
  • git push origin master (推送本地的代码到远程仓库)

        【要输入用户名和密码 username  password】

    7.4、git clone 远程仓库地址 仓库的名字(如果不写默认原仓库名)

  • 其真正的开发中,大家都使用这个
  •  你们的项目老大把项目骨架搭建好之后你们每一个项目小组成员都去把远程的代码拉取到你们的本地去开发
  •  git clone

面向对象编程:

了解面向对象编程思想,需要先了解对象、类、实例。万物皆对象,一切都可以看成对象,什么是类?比如咱们自然界中有很多的生物,咱们可以把这些生物分为:植物、动物。。。,那植物就是一个类,动物也是类,动物还可进行细分,比如:高级动物、低级动物,都是分类。什么是实例呢?比如说人类是一个分类,那具体的某个人,比如:丽丽就是一个人类中的一个实例,我想研究人类有哪些特点,就具体的拿这个人来研究就行。咱们在学习js的时候,也是按照这个思想去学习。

  • 对象:万物皆对象
  • 类:对象的具体细分,按照功能或者特征进行分类
  • 实例:类中具体的一个事物(拿出具体的一个实例进行研究,当前类下的其它实例也会具有这些特点和特征)
  • 面向对象: 面向对象是我们整个编程语言中的一个思想,在编程语言中,对象是一种泛指(一切研究的事物都是对象),我们按照一定的功能和特点,可以把它划分成大类和小类,而类中又有很多的实例,类给实例赋予了一些公有的属性方法而实例自身还可以有自身独有的一些属性和方法,这种伟大的思想就叫面向对象编程思想

设计模式理解:

    <script>
        //面向对象(oop) js 万物皆对象
        //面向过程
        var a = 1 //字面量方式
        var b = new Number(1)
        //单例模式就是一个普通的对象
        //高级单例就是一个函数返回了一个对象:比普通高级在可以有自己的私有变量
        //工厂模式   就是一个普通函数   批量产生一些单例;
    </script>

三、单例设计模式:

单例模式:可以把描述一个事物的所有属性放到一个对象中,这样避免了相互的干扰,这就是单例设计模式

普通单例模式

//普通
var name="刘亦菲";
var age=18;
var sex="女";

var name="胡歌";
var age=18;
var sex="男";

//单例
var obj1={
    name:"刘亦菲",
    age:18,
    sex:"女"
}

var obj2={
    name:"胡歌",
    age:20,
    sex:"男"
}

高级单例模式

var utils=(function(){
     function fn(){},
     var a=2;
     //... 在这个作用域中还有很多的变量和方法,
     return{
        // 想要把谁暴露出去,就放到这对象中
        fn:fn
     }
})();
console.log(nameSpace.fn)

四、工厂设计模式

把实现相同功能的代码进行封装,后期在使用的时候,只用调用这个函数即可,方便后期的“批量生产”。减少了页面中冗余的代码,实现了“高耦合低内聚”。

var person1={
    name:"lili",
    age:18
}

var person2={
    name:"dava",
    age:20
}

//....每次都需要重复的去写,很麻烦,所以就可以用工厂模式

function person(name,age){
  return{
    name:name,
    age:age
  }
   
}

person("lili","18")
person("dava","20")

五、构造函数

// 工厂函数模式
function Person(name, age) {
  var obj = {};
  obj.name = name;
  obj.age = age;
  obj.sayHello = function () {
    console.log("My name is" + this.name, "I am " + this.age + " years old");
  }
  return obj;
}
var p1 = Person("chengxiaohui", 18);
p1.sayHello();


// 构造函数模式
function Person(name, age) {
  var obj = {};
  obj.name = name;
  obj.age = age;
  obj.sayHello = function () {
    console.log("My name is" + this.name, "I am " + this.age + " years old");
  }
  return obj;
}
// 多了一个new
var p1 = new Person("chengxiaohui", 18);
p1.sayHello();

构造函数返回值的情况

  • 默认类中给返回了一个对象
  • 如果写了return,return的是基本数据类型的话,还是返回那个默认对象
  • 如果写了return,return的是引用数据类型,返回的就是return的那个东西

认识new

1、new执行跟普通函数执行的区别

  • 通过new执行了一个函数的时候会先开辟一个堆内存,然后把函数中的this指向这个堆内存
  • 执行过程跟普通函数一样,执行完成之后,若return后边是个引用数据类型,则new执行的返回结果就是return后边的内容,否则就是堆内存
<script>
        //new执行跟普通函数执行的区别:
        /* 
        + 通过new执行一个函数的时候会先开辟一个堆内存,然后把函数中的this指向这个堆内存
        + 执行过程跟普通函数一样,执行完成之后,若ruturn后边是个引用数据类型,则new执行的返回结果就是return后边的内容,否则就是 这个堆内存
        */
        function person(name,age,sex){
                this.name = name
                this.age = age
                this.sex = sex
        }
        person.prototype.eat = function (){}
        person.prototype.eat = function (){}
        var per1 = new person('张三',15,1)//per1就是person类的一个实例
        var per3 = new person('张三',15,1)//per3 就是person类的一个实例
        console.log(per1,per3,per1.eat === per3.eat);
        var ary = new Array()//内置类 (内自带)ary是Array的实例
        //内置类包括:Array Number Boolear Object String Date Function...
        //类  在JS中就是一些函数,只不过是通过new去执行    人类
        //实例   就是通过new执行哪个函数得到的结果         张三
        
        var per2 = {
            name :111,
            age:13,
            sex:1
        }
        console.log(per2);
        //原型模式   构造函数的特殊存储空间

构造函数模式和工厂函数模式的区别?

1、执行的时候

  • 普通函数执行Person函数
  • 构造函数模式是通过new 执行,那Person就是一个类了
  • 函数执行的返回值(p1)就是Person这个类的一个实例

2、在函数代码执行的时候

  • 相同点:
    • 都是形成一个私有作用域,然后形参赋值->预解析(变量提升)->代码从上向下执行
  • 不同点:
    • 在代码执行之前,不用自己手动创建对象,浏览器会默认创建一个对象数据类型的值(这个对象其实就是当前类的一个实例)
    • this代表的就是当前的实例,然后把属性名和属性值赋值给当前的实例
    • 最后浏览器会默认把创建的这个对象返回
// 创建一个数组
var ary=[ ];//字面量方式创建
var ary2=new Array();//构造函数创建
// 无论通过哪种方式去创建,ary和ary2都是Array这个类的实例

1、JS中所有的类都是函数数据类型,他通过new执行变成一个类,但是本质上他也是一个普通函数。

2、在构造函数模式中,类中(函数体)出现的this.xxx=xxx中的this是当前类的一个实例

3、p1和p2都是Person这个类的实例,所以都拥有sayHello这个方法,但是不同实例之间的方法是不一样的,实例和实例之间是单独的个体,所有的私有属性不是同一个。

  • console.log(p1.sayHello===p2.sayHello);//false

构造函数里面代码执行的时候的不同点

// 构造函数模式
function Person(name, age) {
  //在构造函数里,浏览器会默认给你创建一个对象
  //var obj = {};
  obj.name = name;
  obj.age = age;
  obj.sayHello = function () {
    console.log("My name is" + this.name, "I am " + this.age + " years old");
  }
  //浏览器默认返回了
  //return obj;
}
// 多了一个new
var p1 = new Person("chengxiaohui", 18);
var p2 = new Person("zhanghuan", 19);
p1.sayHello();

构造函数执行的时候不传参数可以省略()

function Fn() {

}
//没有写调用的小括号,但是依然会执行这个函数
var f1 = new Fn;
//作为普通函数执行必须要加小括号
Fn();

this的问题:在类中的出现的this.xxx=xxx中的this都是当前类的实例,而某一个属性值(方法),方法中的this需要看方法执行的时候,前面是否有点,才能知道this指向谁

function Fn(name, age) {
  // 这个this指的是f1
  this.name = name;
  this.age = age;
  this.sayHello = function () {
    //这里的this要看这个函数执行的时候才知道
    console.log(this)
  }
}
var f1 = new Fn("chengxiaohui", 18);
f1.sayHello();//this 指的是f1
var f2=f1.sayHello;
f2();//this指的是window
  • 类有普通函数的一面,当函数执行的时候,var num其实只是当前形成的私有作用域中的私有变量而已,他和我们的f1这个实例没有任何的关系
function Fn(name, age) {
  //创建的变量
  var num;
  this.name = name;
  this.age = age;
  this.sayHello = function () {
    console.log(this)
  }
}
var f1 = new Fn("chengxiaohui", 18);
f1.sayHello();
var f2=f1.sayHello;
f2();

构造函数返回值的情况

  • 默认类中给返回了一个对象
  • 如果写了return,return的是基本数据类型的话,还是返回那个默认对象
  • 如果写了return,return的是引用数据类型,返回的就是return的那个东西

instanceof

检测某一个实例是都属于这个类(引伸用途:检测数据类型)

语法:

实例 instanceof 类

console.log(f1 instanceof Fn);
console.log(f1 instanceof Object)

f1和f2都是Fn这个类的一个实例,都拥有name和sayHello两个属性,但是这两个属性是各自的私有属性

function Fn(name) {
  this.name = name;
  this.sayHello = function () {
    console.log(this)
  }
}
var f1 = new Fn("chengxiaohui");
var f2 = new Fn("zhanghuan");

六、原型

构造函数模式中拥有了类和实例的概念,并且实例和实例之间是相互独立的-->实例识别

如何将一个私有属性提升为公有属性呢?

function Fn(name) {
  this.name = name;
}
//放在原型上成了公有属性
Fn.prototype.sayHello=function(){
	console.log("I can say hello~");
}
var f1 = new Fn("chengxiaohui");
var f2 = new Fn("zhanghuan");

需要焊死在脑子里的三句话

  • 1、每一个函数数据类型都有一个天生自带的属性:prototype(原型),这个属性值是一个对象数据类型
  • 2、在prototype上浏览器天生给他加了一个constructor属性,属性值是当前函数(类)本身
  • 3、每一个对象也天生自带一个属性:proto,属性值是当前实例所属类的原型
  • 所有的函数:普通函数、类(内置类,自定义类)都是Function的实例,Function 和Object 都是Function的实例
  • 所有的函数身上都有一个prototype 和__proto__

🖼画图解析

Object是JS中所有对象数据类型的基类(最顶层的类)

  • f1 instanceof Object->true因为f1通过__proto__可以向上查找,不管有多少级,最终都会找到Object上

七、原型链查找机制

f1.hasOwnProperty("x")

  • 1、通过对象.属性名的方式获取到属性值的时候,首先在对象的私有属性上进行查找,如果私有属性上有,就是私有的这个
  • 2、如果私有属性没有,则通过__proto__找到所属类的原型(类的原型上定义的属性和方法都是当前实例的公有属性和方法)
  • 3、如果原型上也没有,则继续通过原型的__proto__继续向上查找,一直到Object.prototype为止

这种查找机制我们就叫做原型链模式!